はじめに
何かとやってくれるActiveRecord。その機能を十分に使いこなせていますか?
僕は、使いこなせてません!笑
今回は、そんなActiveRecordのattribute methodのうち、BeforeTypeCastのメソッドについてまとめていきます。
(2022年3月時点。Rails7.0対応。)
検証環境
以下のschemaとmodelに基づいて検証を行なっています。
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
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編)