inverse_of とは
ActiveRecord で双方向の関連付けをしている以下のようなクラスがあるとする。
class Customer
has_many :orders
end
class Order
belongs_to :customer
end
同じ Customer を指しているのに
次のような変更を加えると
データの不整合が生じてしまう。
c = Customer.first
o = c.orders.first
c.first_name = "Change"
c.first_name == o.customer.first_name #=> false
これは、同じデータを持つ別々のオブジェクトであることが原因。
c = Customer.first
o = c.orders.first
c.equal? o.customer #=> false
inverse_of
を使うと、同じオブジェクトをみるようになり、
このようなデータの不整合が生じなくなるとともに
無駄にオブジェクトを生成しないので、アプリケーションの効率もよくなる。
Q: いつも使えばいいのでは?
オプション指定する必要があるということは、inverse_of
を使いたくないタイミングなんてのがあるのだろうかと疑問に思った。
A: Rails4.1 以降はデフォルト化されていた
結局、 inverse_of
を使いたくないタイミングというのは見つけられず、
代わりに、 inverse_of
は自動で設定されるようになったということがわかった。
この記事が一番わかりやすかった。
Automatic Inverse Associations に至るまでの経緯から その実現方法について簡単な説明付き。
http://wangjohn.github.io/activerecord/rails/associations/2013/08/14/automatic-inverse-of.html
上の記事によるとこのコミットで追加されている。
https://github.com/rails/rails/commit/26d19b4661f3d89a075b5f05d926c578ff0c730f
ただし、自動で inverse_of
を設定してくれるのは
:has_many, :has_one, :belongs_to 関連付けに対してだけ。
:conditions, :through, :polymorphic, :foreign_key などを使用した複雑な名前付けが絡んでくると、set_automatic_inverse_of
メソッドの扱える範囲を越えてしまう。