From b418f8c6a217a9041b1c2cfc034a6aebbf633682 Mon Sep 17 00:00:00 2001 From: Murray Steele Date: Sun, 31 May 2009 22:14:02 +0100 Subject: Documenting :inverse_of options for associations. --- activerecord/lib/active_record/associations.rb | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index eb80f5e8d2..a5e2afa785 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -641,6 +641,60 @@ module ActiveRecord # end # end # + # == Bi-directional associations + # + # When you specify an association there is usually an association on the associated model that specifies the same + # relationship in reverse. For example, with the following models: + # + # class Dungeon < ActiveRecord::Base + # has_many :traps + # has_one :evil_wizard + # end + # + # class Trap < ActiveRecord::Base + # belongs_to :dungeon + # end + # + # class EvilWizard < ActiveRecord::Base + # belongs_to :dungeon + # end + # + # The +traps+ association on +Dungeon+ and the the +dungeon+ association on +Trap+ are the inverse of each other and the + # inverse of the +dungeon+ association on +EvilWizard+ is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default, + # +ActiveRecord+ doesn't do know anything about these inverse relationships and so no object loading optimisation is possible. For example: + # + # d = Dungeon.first + # t = d.traps.first + # d.level == t.dungeon.level # => true + # d.level = 10 + # d.level == t.dungeon.level # => false + # + # The +Dungeon+ instances +d+ and t.dungeon in the above example refer to the same object data from the database, but are + # actually different in-memory copies of that data. Specifying the :inverse_of option on associations lets you tell + # +ActiveRecord+ about inverse relationships and it will optimise object loading. For example, if we changed our model definitions to: + # + # class Dungeon < ActiveRecord::Base + # has_many :traps, :inverse_of => :dungeon + # has_one :evil_wizard, :inverse_of => :dungeon + # end + # + # class Trap < ActiveRecord::Base + # belongs_to :dungeon, :inverse_of => :traps + # end + # + # class EvilWizard < ActiveRecord::Base + # belongs_to :dungeon, :inverse_of => :evil_wizard + # end + # + # Then, from our code snippet above, +d+ and t.dungeon are actually the same in-memory instance and our final d.level == t.dungeon.level + # will return +true+. + # + # There are limitations to :inverse_of support: + # + # * does not work with :through associations. + # * does not work with :polymorphic associations. + # * for +belongs_to+ associations +has_many+ inverse associations are ignored. + # # == Type safety with ActiveRecord::AssociationTypeMismatch # # If you attempt to assign an object to an association that doesn't match the inferred or specified :class_name, you'll @@ -781,6 +835,10 @@ module ActiveRecord # If false, don't validate the associated objects when saving the parent object. true by default. # [:autosave] # If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default. + # [:inverse_of] + # Specifies the name of the belongs_to association on the associated object that is the inverse of this has_many + # association. Does not work in combination with :through or :as options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional assocations for more detail. # # Option examples: # has_many :comments, :order => "posted_on" @@ -890,6 +948,10 @@ module ActiveRecord # If false, don't validate the associated object when saving the parent object. +false+ by default. # [:autosave] # If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default. + # [:inverse_of] + # Specifies the name of the belongs_to association on the associated object that is the inverse of this has_one + # association. Does not work in combination with :through or :as options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional assocations for more detail. # # Option examples: # has_one :credit_card, :dependent => :destroy # destroys the associated credit card @@ -990,6 +1052,10 @@ module ActiveRecord # [:touch] # If true, the associated object will be touched (the updated_at/on attributes set to now) when this record is either saved or # destroyed. If you specify a symbol, that attribute will be updated with the current time instead of the updated_at/on attribute. + # [:inverse_of] + # Specifies the name of the has_one or has_many association on the associated object that is the inverse of this belongs_to + # association. Does not work in combination with the :polymorphic options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional assocations for more detail. # # Option examples: # belongs_to :firm, :foreign_key => "client_of" -- cgit v1.2.3