ActiveRecord4, Rails4のinverse_ofについて理解したメモ
MongoDB(mongoid)でも使える。
inverse_ofとは
inverse_ofを指定したリレーションのある2つのモデルでは、双方から同一のインスタンスを参照できるようになる。両者ともメモリ上で同一のインスタンスとして扱われる。
逆に、inverse_ofの設定が無いと同一として扱われず、一方からの変更がもう一方から参照しても変更されていない。
具体例
UserモデルとMenuモデルが1対多でリレーションしている状況を考える。Userが複数のMenuを登録できるWebサービスのイメージ。
class User < ActiveRecord::Base has_many :menus end class Menu < ActiveRecord::Base belongs_to :user end
inverse_ofが無かったら
Userのフィールドnameの変更が、Menuからたどった場合に変更が参照できない。メモリ上で別インスタンスとして扱われているから。
user = User.first menu = user.menus.first user.name == menu.user.name # => true user.name = "change" user.name == menu.user.name # => false
inverse_ofを指定すると
class User < ActiveRecord::Base has_many :menus, inverse_of: :user end class Menu < ActiveRecord::Base belongs_to :user, inverse_of: :menus end
メモリ上で同一インスタンスとして扱われるようになり、userもしくはuser.menuからnameを変更しても、常にuser.name == menu.user.name
がtrueを返すようになる。