This project is archived and is in readonly mode.

#2912 ✓resolved
Thomas Watson

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 #&lt;Class:0x3e4f298&gt;</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

  • Jeremy Kemper

    Jeremy Kemper May 4th, 2010 @ 06:48 PM

    • Milestone changed from 2.x to 3.x
  • Dan Pickett

    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

    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.

    http://github.com/ldenman/rails-bm-ticket-2912

  • Jeff Kreeftmeijer

    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

    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 uses update_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 a has_one in place of the has_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.

  • blatyo
  • Jon Leighton

    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>

Attachments

Pages