This project is archived and is in readonly mode.

#3527 ✓stale
Dr Nic

undefined method `destroyed?' for ActiveRecord::Associations::BelongsToAssociation

Reported by Dr Nic | November 30th, 2009 @ 11:46 PM | in 2.3.10

I upgraded an app from 2.3.4 to 2.3.5 and am getting the following errors within nearly all my integration tests

undefined method `destroyed?' for #<ActiveRecord::Associations::BelongsToAssociation:0x5c57ac4> (NoMethodError)

The destroyed? method seems new in 2.3.5 but only implemented on the Base class.

Thoughts?

Comments and changes to this ticket

  • Roland Moriz

    Roland Moriz December 1st, 2009 @ 01:44 PM

    • Tag changed from activerecord to 2.3.5, activerecord

    I can confirm this on my apps after running Rails 2.3.5. Effectively breaks the apps.

  • Jeff Tucker

    Jeff Tucker December 1st, 2009 @ 03:41 PM

    • Tag cleared.

    I can confirm this as well. It seems to only affect polymorphic associations though?

  • Jeff Tucker

    Jeff Tucker December 1st, 2009 @ 04:33 PM

    • Tag set to 2.3.5, activerecord, rspec_rails

    Found a solution for my case -- this is a (new) problem with rspec-rails, not ActiveRecord. Using mock_model creates an AR mock with standard methods built in. Apparently destroyed? is a standard method in the association process now, so mock_model instances balk when they get pushed into an association. I resolved this by patching rspec-rails' mock.rb:

          def mock_model(model_class, options_and_stubs = {})
            id = options_and_stubs[:id] || next_id
            options_and_stubs = options_and_stubs.reverse_merge({
              :id => id,
              :to_param => id.to_s,
              :new_record? => false,
          :destroyed? => false, # new stub to handle AR associations
              :errors => stub("errors", :count => 0)
            })
            ...
    
  • PommyTom

    PommyTom December 3rd, 2009 @ 08:32 PM

    Jeffs' fix worked for me... Thanks!

  • Lee
  • Andrew Bortz

    Andrew Bortz December 3rd, 2009 @ 10:02 PM

    • Tag changed from 2.3.5, activerecord, rspec_rails to 2.3.5, activerecord, activeresource, rspec_rails

    Actually, for us this was because ActiveResource has not been kept in sync with ActiveRecord, and doesn't implement #destroyed?. When a resource is used through an association... bang!

    Just curious: how abandonware is ActiveResource at the moment?

  • Andrew Bortz

    Andrew Bortz December 16th, 2009 @ 09:18 PM

    • Tag changed from 2.3.5, activerecord, activeresource, rspec_rails to 2.3.5, 2.3.6, activerecord, activeresource, rspec_rails

    Since this is a regression in 2.3.5, can we expect it to be fixed in .6?

  • McClain Looney

    McClain Looney February 17th, 2010 @ 10:42 PM

    i've just run into this using has_many_polymorphs in conjunction with will_paginate and accepts_nested_attrs_for. Bit of a show stopper for us unfortunately. happens when updating an existing record via accept_nested_attributes.

    rails 2.3.5

  • José Valim

    José Valim February 21st, 2010 @ 12:45 PM

    Is this a rspec-rails or Rails issue? Could someone please provide a failing test case?

  • Ryan Bigg

    Ryan Bigg May 25th, 2010 @ 10:54 AM

    • State changed from “new” to “open”

    Please provide more information on this ticket, especially how to duplicate it.

    Is it still broken in 2.3.6?

  • acechase

    acechase June 4th, 2010 @ 10:56 PM

    This is still broken as of rails 2.3.8. Unlike some other folks who've reported this problem, we are not using rspec, we use Flexmock. When are seeing this problem after upgrading from rails 2.2.2 to rails 2.3.8. It looks to happen whenever interacting with associations that are on a mocked AR::Base inheriting class. To work around the problem we added the following code into our flexmock_test_helper (ghetto, but works as a short term solution):

    
    class MockBelongsToAssociation < ActiveRecord::Associations::BelongsToAssociation
      # see rails ticket https://rails.lighthouseapp.com/projects/8994/tickets/3527-undefined-method-destroyed-for-activerecordassociationsbelongstoassociation                                                                             
      def destroyed?
        false
      end
    
      def reload
        # No op                                                                                                                                                                                                                             
      end
    end
    
    class ActiveRecord::Associations::BelongsToAssociation
      # see rails ticket https://rails.lighthouseapp.com/projects/8994/tickets/3527-undefined-method-destroyed-for-activerecordassociationsbelongstoassociation                                                                             
      def destroyed?
        false
      end
    end
    
    
    class ActiveRecord::Associations::BelongsToPolymorphicAssociation
      # see rails ticket https://rails.lighthouseapp.com/projects/8994/tickets/3527-undefined-method-destroyed-for-activerecordassociationsbelongstoassociation                                                                             
      def destroyed?
        false
      end
    end
    

    Obviously this hack isn't the greatest since presumably there are times when destroyed? should actually be returning true.

    I don't fully understand what the new destroyed? method is doing and in what context it is being called from... the stack traces weren't incredibly helpful that come from our failed tests. It seems that the easiest way to replicate the problem is to mock and AR class and then attempt to change one of the associations on that class (problem happens with both has_* and belongs_to associations). It seems that the new destroyed? method is unexpected by the existing mocking frameworks...

  • acechase

    acechase June 4th, 2010 @ 11:04 PM

    Quick addition:

    I tested this with Flexmock V0.8.3, then after writing the above comment went back and upgraded Flexmock to v0.8.6 and the problem remains.

    Looking at the usage of AR::Base#destroyed?, it looks like this is now valid AR code that mocking frameworks need to be updated to support?

  • acechase

    acechase June 4th, 2010 @ 11:14 PM

    Jeez... I apologize for not having all this better coalesced before posting but I now need to add an additional note.

    So, Flexmock has capacity for mocking AR::Base objects, but it doesn't mock the associations hanging off the object. As soon as you interact with an association from a mocked object then you're right back to interacting with the DB. To avoid this (I had forgotten about this part), we (my fellow engineers at glyde.com) add in our own association mocking in our flexmock_test_helper.

    So my previous comment, that the problem is in the mocking frameworks ballpark, probably applies to some frameworks, but for my companies code base I guess it's on us to fix :)

    I guess I'll need to dig into the AR::Base code to see how a mock should properly track whether or not it's associations are destroyed.

  • Harm Aarts

    Harm Aarts June 8th, 2010 @ 11:37 AM

    • Tag changed from 2.3.5, 2.3.6, activerecord, activeresource, rspec_rails to 2.3.5, 2.3.6, 2.3.8, activerecord, activeresource, rspec_rails

    The problem persists with Rails 2.3.8 and rspec-rails 1.3.2 (which includes Lee's patch). I believe the problem is related to ActiveResource.

  • coffeeaddict_nl

    coffeeaddict_nl June 29th, 2010 @ 02:47 PM

    • Importance changed from “” to “”

    This doesn't only happen on rspec-rails. It happens in real world apps (eg: non test cases) as well. My best bet is that ActiveRecord::Associations::AssociationProxy should be defining a respond_to? along side with the method_missing.

    I will try to figure out how to do this, cause it is starting to bug me more than I can handle...

  • Santiago Pastorino

    Santiago Pastorino June 29th, 2010 @ 06:35 PM

    • Milestone set to 2.3.9
  • coffeeaddict_nl

    coffeeaddict_nl June 30th, 2010 @ 07:01 AM

    This looks as if it is very closely related to #1515 and #2378 (still looking for a solution, but this might be of help to someone interested...)

  • coffeeaddict_nl

    coffeeaddict_nl June 30th, 2010 @ 02:51 PM

    /me bows head in shame.

    It turns out to be user error on my part.

  • Harm Aarts

    Harm Aarts July 1st, 2010 @ 09:17 AM

    I believe this bug has something to do with this commit:
    http://github.com/rails/rails/commit/d916c62cfc7c59ab6411407a05b946...

    I also begin to doubt if it has anything to do with rspec.

  • Michael Edgar

    Michael Edgar August 22nd, 2010 @ 01:21 AM

    During a 2.3.4 to 2.3.8 upgrade trial, our tests started failing with this as well.

    The issue arose specifically when testing whether objects were valid that had associated objects we had mocked out. Previously we had (real models changed):

    @author = flexmock(:model, Author)
    @author.should_receive(:valid?).and_return(true)
    assert_valid Comment.new(:author => @author)
    

    Which would pass. Under the newer versions of Rails, it would give the same issue everyone's had: no destroyed? method.

    In later versions of rails (I'm looking at 2.3.8 right now), #association_valid? is now defined at rails/activerecord/lib/active_record/autosave_association.rb:278, which immediately calls destroyed? and marked_for_destruction? on the associated object in question. Thus, if a mocked associated object needs to have its validity checked, it will have to respond to both destroyed? and marked_for_destruction?. We've changed our code to:

    @author = flexmock(:model, Author)
    @author.should_receive(:valid?).and_return(true)
    @author.should_receive(:destroyed?).and_return(true)
    @author.should_receive(:marked_for_destruction?).and_return(true)
    assert_valid Comment.new(:author => @author)
    

    In the necessary places, and this pain point is no longer an issue. This is, in my opinion, not within Rails' scope. Flexmock (and rspec-rails, if this issue is still a problem for that library) should consider including these methods (valid?, destroyed?, marked_for_destruction?) when one uses flexmock(:model, ModelType).

  • Jeremy Kemper

    Jeremy Kemper August 30th, 2010 @ 02:28 AM

    • Milestone changed from 2.3.9 to 2.3.10
  • Michael MacDonald

    Michael MacDonald September 19th, 2010 @ 03:39 PM

    I'm experiencing the same problem but I'm using Rails 3.0.0 and it's with a Cucumber (0.9.0 in git) feature where I'm using Machinist (1.0.6) to create a new ActiveRecord object which has a belongs_to association with an ActiveResource object. I'm using Dupe (rails3 branch) to stub out this ActiveResource object. I suspect the problem lies with either Machinist or Dupe. After reading this ticket, I added a destroyed? method into my activeresource class in my test environment (as detailed by acechase) and now it all works for me.

  • David Trasbo

    David Trasbo September 23rd, 2010 @ 09:37 AM

    • State changed from “open” to “needs-more-info”

    People seem to report this error to happen under many different types of circumstances.

    We need a minimal way to reproduce this, a failing test, or a patch.

  • Michael MacDonald

    Michael MacDonald October 3rd, 2010 @ 11:23 PM

    • Tag changed from 2.3.5, 2.3.6, 2.3.8, activerecord, activeresource, rspec_rails to 2.3.5, 2.3.6, 2.3.8, activerecord, activeresource

    Coming back to this problem again I realise that it has nothing to do with rspec or with my test setup. The problem exists when using a rails app > 2.3.4 to connect to an existing activeresource (regardless what version of rails that activeresource is running).

    Here's the steps I've used to generate the error:

    • Using rails 2.3.8 via rvm:
        mkdir ~/rails_ticket_3527
        cd rails_ticket_3527
        rvm use 1.8.7@rails238 --create
        gem install rails -v=2.3.8
        gem install sqlite3-ruby
        
        rails clients
        cd clients
        rake db:create
        script/generate scaffold Client
        rake db:migrate
        script/server
    

    Now the resource is running on localhost port 3000.

    • Now via your browser or console, create the first client object

    • Using rails 2.3.4 via rvm:

        cd ~/rails_ticket_3527
        rvm use 1.8.7@rails234 --create
        gem install rails -v=2.3.4
        gem install sqlite3-ruby
    
        rails blog234
        cd blog234
        rake db:create
        script/generate scaffold User client_id:integer
        rake db:migrate
        echo 'class Client < ActiveResource::Base; self.site = "http://localhost:3000"; end' > app/models/client.rb
        echo 'class User < ActiveRecord::Base; belongs_to :client; end' > app/models/user.rb
    
    • Now via script/console in the blog234 app:
        user = User.create
        user.client = Client.find(1)
        user.save
    
    • Repeat the same steps for a rails 2.3.5 app.

    Result: It works in rails 2.3.4 but not in rails 2.3.5.

    I hope that helps!

  • Ryan Bigg

    Ryan Bigg October 9th, 2010 @ 10:12 PM

    • Tag cleared.

    Automatic cleanup of spam.

  • Ryan Bigg

    Ryan Bigg October 19th, 2010 @ 08:23 AM

    Automatic cleanup of spam.

  • Ryan Bigg

    Ryan Bigg October 19th, 2010 @ 08:23 AM

    Automatic cleanup of spam.

  • José Valim

    José Valim October 20th, 2010 @ 01:34 PM

    • State changed from “needs-more-info” to “stale”
  • Michael MacDonald

    Michael MacDonald October 20th, 2010 @ 02:20 PM

    • Title changed from “Add magic encoding comment to generated files” to “undefined method `destroyed?' for ActiveRecord::Associations::BelongsToAssociation”
  • Jeff Kreeftmeijer
  • Tim Morton

    Tim Morton April 25th, 2011 @ 09:56 PM

    I can confirm a few things about this issue:

    1) It's still present in 2.3.11.
    2) As a few other people have explained above, the problem occurs when you have a relationship between ActiveRecord and ActiveResource models.
    3) Put this code in an initializer to fix the problem:

    class ActiveResource::Base
      def destroyed?
        false
      end
    end
    

    I'll see if I can get a real unit test and fix later this week.

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