LoginSignup
3
0

More than 1 year has passed since last update.

ActiveRecord attribute methodまとめ(その①: BeforeTypeCast編)

Last updated at Posted at 2022-03-08

はじめに

何かとやってくれるActiveRecord。その機能を十分に使いこなせていますか?
僕は、使いこなせてません!笑
今回は、そんなActiveRecordのattribute methodのうち、BeforeTypeCastのメソッドについてまとめていきます。
(2022年3月時点。Rails7.0対応。)

検証環境

以下のschemaとmodelに基づいて検証を行なっています。

db/schema.rb
create_table "todos", charset: "utf8mb4", force: :cascade do |t|
  t.string "title"
  t.datetime "schedule_at"
  t.integer "status"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end
app/model/todo.rb
class Todo < ApplicationRecord
  enum status: { not_yet: 0, complete: 1, in_progress: 2, cancel: 3 }
end

BeforeTypeCast

型キャストされる前の値を取得するメソッド群です。
enumを使ったり、独自にattributeを定義して使ったりする時にはお世話になります。

attributes_before_type_cast

attributes_before_type_castを用いると、型キャスト前の情報でattributeのハッシュが取得できます。

todo = Todo.new(status: :complete, schedule_at: '2022-02-22 22:22:22')
todo.attributes 
#=> {..., "schedule_at"=>Tue, 22 Feb 2022 22:22:22.000000000 JST +09:00, "status"=>"complete", ...}
todo.attributes_before_type_cast
#=> {..., "schedule_at"=>"2022-02-22 22:22:22", "status"=>:complete, ...}

[attribute名]_before_type_cast

[attribute名]_before_type_castで特定のattributeの型キャスト前の値が取得可能です。

todo.schedule_at #=> Tue, 22 Feb 2022 22:22:22.000000000 JST +09:00
todo.schedule_at_before_type_cast #=> "2022-02-22 22:22:22"

attributes_for_database

attributes_for_databaseは、データベースに入る型にキャストされたatttibuteのハッシュを返します。
このメソッドはRails7.0から追加されました。

todo = Todo.new(status: :complete, schedule_at: '2022-02-22 22:22:22')
todo.attributes
#=> {..., "schedule_at"=>Tue, 22 Feb 2022 22:22:22.000000000 JST +09:00, "status"=>"complete", ...}
todo.attributes_for_database
#=> {..., "schedule_at"=>"2022-02-22 22:22:22 +0900", "status"=>1, ...}

[attribute名]_for_database

[attribute名]_for_databaseを用いると、特定のattributeの値をデータベースに入る型で取得できます。
attributes_for_databaseと同様に、Rails7.0から追加されたのかと思いきや、Rails6.1からこっそり存在していました。

todo.status #=> "complete"
todo.status_for_database #=> 1

下の例のように、入ってくる値がデータベースの型の時、_before_type_cast, _for_databaseの両方とも同じ値を返しますが、動作が同じものと誤解しないように注意してください。

todo = Todo.new(status: 2)
todo.status #=> "in_progress"
todo.status_before_type_cast #=> 2
todo.status_for_database #=> 2

read_attribute_before_type_cast

[attribute名]_before_type_castと同様に、指定したattributeの型キャスト前の値を返します。
[attribute名]_before_type_castの場合は、存在しないattributeに対して実行するとNoMethodErrorの例外を吐きますが、read_attribute_before_type_castでは、存在しないattribute名を指定すると、Exceptionではなくnilを返します。

todo = Todo.new(status: :complete, schedule_at: '2022-02-22 22:22:22')
todo.read_attribute(:status) #=> "complete"
todo.read_attribute_before_type_cast(:status) #=> :complete

# 存在しないattribute名を指定すると、nilを返す
todo.read_attribute_before_type_cast(:no_attribute)#=> nil

# 存在しないattributeに対して実行するとNoMethodErrorの例外を吐く
todo.no_attribute_before_type_cast
#=> NoMethodError (undefined method `no_attribute_before_type_cast' for ....

おわりに

今回は、BeforeTypeCastについてまとめていきました。
普段あまり意識せずに使っているメソッドも、しっかり考えてみると奥深いものですね。

その他のメソッドについては、別記事でまとめています。↓↓
ActiveRecord attribute methodまとめ(その②: Dirty編)
Active Record attribute methodまとめ(その③: PrimaryKey編)
Active Record attribute methodまとめ(その④: Query, Read, Write編)

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0