0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ドット記法で値にアクセスできない…

Last updated at Posted at 2019-05-24

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は、変更前の値を追跡できたりするので、
かなり便利ですね!

参考記事

@sakuro さん
@scivola さん
ご指摘ありがとうございました!

0
0
3

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?