RailsのActive Recordにおいて、例えば、Userモデルのインスタンスはドット記法を用いてその属性値にアクセスできることはご存知かと思います。
例)
>> user = User.new(name: "hoge", email: "hoge@example.com")
>> user.name
=> "hoge"
ですが、ドット記法を用いて属性値にアクセスできないことがあったので、シェアしたいと思います。
#バージョン
Rails:5.1.4
ruby:ruby 2.6.0p0
#状況
例えば、勤怠を管理するモデルでAttendanceモデルがあるとする。
id | time_in | time_out | time_in_change | time_out_change |
---|---|---|---|---|
1 | 09:00 | 18:00 | 10:00 | 19:00 |
︙ | ︙ | ︙ | ︙ | ︙ |
この時、
例)
>> attendance = Attendance.find(1)
>> attendance.time_in
=> "09:00"
となり、ドット記法でアクセスできるが、time_in_change及びtime_out_changeカラムの場合は、
例)
>> attendance = Attendance.find(1)
>> attendance.time_in_change
=> nil
でドット記法で属性値にアクセスできない現象が発生しました。
似たような現象が起こっている記事を発見し、→ 参考記事
試しに、
例)
>> attendance = Attendance.find(1)
>> attendance.attributes['time_in_change']
=> "10:00"
でドット記法で値にアクセスできるが、なぜなのか原因が分からず…
さらに、試みて
time_in_change → change_time_in
time_out_change → change_time_out
とカラム名を変更すると、
例)
>> attendance = Attendance.find(1)
>> attendance.change_time_in
=> "10:00"
となり、attributesを使用しなくても値にアクセスできるようになりました。
カラム名の命名に問題があるのでしょうか?
#最後に
今回の現象について、原因が何であるか分からないため、この記事を読んでくださった方で
何か原因が思い当たるようでしたら、アドバイス頂けると幸いです。
よろしくお願いします。
@sakuro さん
@scivola さん
よりご指摘頂きました。
どうやら、
今回の場合、time_inカラムが存在していて、
.time_in_changeとすると、.time_in_changeカラムの属性値に
アクセスするのではなく、ActiveModel::Dirtyモジュールに定義されている
time_in_changeメソッドが呼び出されるみたいです。
※カラム名_changeで呼び出される。
今回の属性値にアクセスできるか否かの件とは関係ありませんが、
ActiveModel::Dirtyは、変更前の値を追跡できたりするので、
かなり便利ですね!