LoginSignup
0
0

More than 5 years have passed since last update.

モデルのクラスメソッドであるattributesとインスタンスメソッドであるattributesは返すものが違う

Last updated at Posted at 2016-07-19

クラスメソッドとインスタンスメソッドは違う(当然)

属性名の一覧を取得するときによく使うattributesについて、モデルに対して呼ぶときと、モデルのインスタンスに対して呼ぶときとでは違う値が返る。
いやそりゃクラスメソッドとインスタンスメソッドは違うものなんだから当たり前なんですけど、大体のケースで同じ値を返すので意外と気づきにくかったりする。ということは、稀にそれが原因でよくわからないエラーを踏んで爆発したりするのでメモ。

具体的には

モデルの属性はRailsが起動したときにロードされ、インスタンスの属性はそれが取得されたときにロードされる。

実例

違いがわかりやすいようにattribute_namesを使って実験。

[1] pry(main)> User.attribute_names
=> ["id", "name", "email", "created_at", "updated_at"]
[2] pry(main)> u = User.first
  User Load (0.5ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1
=> #<User:0x007ffd6f881fe8 id: 1, name: "Taro", email: "foo@bar.com", created_at: Sat, 16 Jul 2016 11:06:18 UTC +00:00, updated_at: Sat, 16 Jul 2016 11:06:18 UTC +00:00>
[3] pry(main)> u.attribute_names
=> ["id", "name", "email", "created_at", "updated_at"]

見た感じでは一緒。ここでmigrateしてtableにcolumnを追加。

$ bundle exec rake db:migrate
== 20160719032723 AddClassificationToUsers: migrating =========================
-- add_column(:users, :classification, :integer, {:default=>0})
   -> 0.0048s
== 20160719032723 AddClassificationToUsers: migrated (0.0050s) ================

Userのレコードを再度取得してインスタンスを生成。

[4] pry(main)> User.attribute_names
=> ["id", "name", "email", "created_at", "updated_at"]
[5] pry(main)> u = User.first
  User Load (0.4ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1
=> #<User:0x007ffd6a208248 id: 1, name: "Taro", email: "foo@bar.com", created_at: Sat, 16 Jul 2016 11:06:18 UTC +00:00, updated_at: Sat, 16 Jul 2016 11:06:18 UTC +00:00>
[6] pry(main)> u.attribute_names
=> ["id", "name", "email", "created_at", "updated_at", "classification"]

モデルに対する実行結果と、インスタンスに対する実行結果に違いが出た。
モデルについては、Railsが再起動されていないため属性に変化がない。
一方でインスタンスについては、取得時にtableのデータをロードしてくるため、その際に新たな属性を認識する(値がNULLのときは認識しないが、今回はdefault値を設定している)。

[7] pry(main)> reload!
Reloading...
=> true
[8] pry(main)> User.attribute_names
=> ["id", "name", "email", "created_at", "updated_at", "classification"]

Railsを再起動すると、モデルでも属性を認識する。

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