Rails / inverse_ofでメモリ効率化
ここに記載がある inverse_of。
あんまり意識した事なかったけど使った方がいいんだね。
http://railsguides.jp/active_record_validations.html#presence
こういう関係だとします。
ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Place < ActiveRecord::Base
has_many :shops
accepts_nested_attributes_for :shops
end
class Shop < ActiveRecord::Base
belongs_to :place
validates :name, presence: true
validates :owner, presence: true
end
こうしてみる。
ruby
1
2
3
4
5
6
7
# irb(main):001:0>
place = Place.create(name: "Favorite Place")
shop = place.shops.create(name: "Nice Shop", owner: "Sawada")
shop.place == place
#Place Load (1.1ms) SELECT "places".* FROM "places" WHERE "places"."id" = $1 LIMIT 1 [["id", 6]]
=> true
なのに対し、
has_many :shops, inverse_of: :place
としてみると…
ruby
1
2
3
# irb(main):003:0>
shop.place == place
=> true
あら、データベースを叩いてない。すてき。
A model's associations, as far as memory is concerned, are one-way bindings. The :inverse_of option basically gives us two-way memory bindings when one of the associations is a :belongs_to.
http://viget.com/extend/exploring-the-inverse-of-option-on-rails-model-associations
2方向のアソシエーションをしてくれるからメモリの効率がいいと。
というか普通のアソシエーションが1方向だけだとは知らなかった。
と、思ったら、
自動でやってくれるらしい。
Every association will attempt to automatically find the inverse association and set the :inverse_of option heuristically (based on the association name). Most associations with standard names will be supported.
ただし、これらのオプションがついていないアソシエーションに関してのみなので注意。
:conditions
:through
:polymorphic
:foreign_key
でも上の例は Rails 4.0.13 での実行例。
指定しないと有効になってないのはなぜ…。
参考
http://viget.com/extend/exploring-the-inverse-of-option-on-rails-model-associations
http://gsusmonzon.blogspot.com.br/2011/09/rails-power-of-inverseof.html
http://guides.rubyonrails.org/association_basics.html