This project is archived and is in readonly mode.
has_one through doesn't work when going through a collection association
Reported by Thomas Watson | July 15th, 2009 @ 10:43 PM | in 3.x
When using alias_method
to override a setter method
for a has_one :through association, an undefined
method
error occurs when the alias method is called:
undefined method
update_attributes' for #<Class:0x3e4f298></code> </pre>
This bug was introduced between Rails v2.2.1 and v2.2.2 in commit [a5609cd3cf3921cbd17b6314498318da7d522395] in the file has_one_through_association.rb.
This code sets the stage:
class Foo < ActiveRecord::Base
has_many :foobars
has_one :bar, :through => :foobars
alias_method :orig_bar=, :bar=
def bar=(value)
Now just run this in your console to replicate the problem:
Foo.new.bar = Bar.new
self.orig_bar = value
end end
class Foobar < ActiveRecord::Base belongs_to :foo belongs_to :bar end
class Bar < ActiveRecord::Base end
Comments and changes to this ticket
-
Dan Pickett May 9th, 2010 @ 07:20 PM
- Tag changed from 2.2.2, activerecord, alias_method, associations, has_one_through, update_attributes to 2.2.2, activerecord, alias_method, associations, bugmash, has_one_through, update_attributes
can a bugmasher review this against master?
-
Lake May 14th, 2010 @ 10:49 PM
- Tag changed from 2.2.2, activerecord, alias_method, associations, bugmash, has_one_through, update_attributes to 2.2.2, 3.0.0.beta, activerecord, alias_method, associations, bugmash, has_one_through, update_attributes
It appears that this happens even if we don't use alias_method...
I have posted some code on github to try and help identify the issue. Check the readme for a quick overview.
-
Jeff Kreeftmeijer May 15th, 2010 @ 04:56 PM
- Tag changed from 2.2.2, 3.0.0.beta, activerecord, alias_method, associations, bugmash, has_one_through, update_attributes to 2.2.2, 3.0.0.beta, activerecord, alias_method, associations, bugmash, has_one_through, update_attributes, verified
Verified with Thomas' code snippet against master and Lake's github repo (also, master).
And here's a cleaned up version of Thomas' code:
class Foo < ActiveRecord::Base has_many :foobars has_one :bar, :through => :foobars alias_method :orig_bar=, :bar= def bar=(value) self.orig_bar = value end end class Foobar < ActiveRecord::Base belongs_to :foo belongs_to :bar end class Bar < ActiveRecord::Base end
And run this in the console:
Foo.new.bar = Bar.new
-
Jon Leighton December 19th, 2010 @ 02:19 PM
- Assigned user set to Aaron Patterson
- Title changed from has_one through fails when setter is overridden using alias_method to has_one through doesn't work when going through a collection association
- Tag changed from 2.2.2, 3.0.0.beta, activerecord, alias_method, associations, bugmash, has_one_through, update_attributes, verified to 2.2.2, 3.0.0.beta, activerecord, alias_method, associations, bugmash, has_one_through, patch, update_attributes
This is not actually a problem with aliases at all.
The problem is with putting a
has_one
association:through
a collection (i.e.has_many
).HasOneThroughAssociation#create_through_record
looks up the through association, and expects it to be a single record. On this assumption it usesupdate_attributes
, which obviously isn't defined on a collection. Hence the problem.My preferred solution is to make it invalid to put a
has_one
through a collection. If the user really wants to go through an association that could have many different records, they can explicitly add ahas_one
in place of thehas_many
, and use a combination of:order
,:conditions
etc to be specific about which record they want.I've attached a tested patch which prohibits
has_one
associations going through collections. -
Jon Leighton December 23rd, 2010 @ 11:53 PM
- State changed from new to resolved
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>