diff options
Diffstat (limited to 'activerecord/lib/active_record/associations.rb')
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 7f299b2aa5..f494e38e2f 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -42,11 +42,12 @@ module ActiveRecord end end - class HasManyThroughCantAssociateThroughHasManyReflection < ActiveRecordError #:nodoc: + class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc: def initialize(owner, reflection) super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.") end end + class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc: def initialize(owner, reflection) super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.") @@ -416,6 +417,32 @@ module ActiveRecord # @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm # @firm.invoices # selects all invoices by going through the Client join model. # + # Similarly you can go through a +has_one+ association on the join model: + # + # class Group < ActiveRecord::Base + # has_many :users + # has_many :avatars, :through => :users + # end + # + # class User < ActiveRecord::Base + # belongs_to :group + # has_one :avatar + # end + # + # class Avatar < ActiveRecord::Base + # belongs_to :user + # end + # + # @group = Group.first + # @group.users.collect { |u| u.avatar }.flatten # select all avatars for all users in the group + # @group.avatars # selects all avatars by going through the User join model. + # + # An important caveat with going through +has_one+ or +has_many+ associations on the join model is that these associations are + # *read-only*. For example, the following would not work following the previous example: + # + # @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around. + # @group.avatars.delete(@group.avatars.last) # so would this + # # === Polymorphic Associations # # Polymorphic associations on models are not restricted on what types of models they can be associated with. Rather, they @@ -819,7 +846,7 @@ module ActiveRecord # [:through] # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt> # are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt> - # or <tt>has_many</tt> association on the join model. + # <tt>has_one</tt> or <tt>has_many</tt> association on the join model. # [:source] # Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be # inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or |