This project is archived and is in readonly mode.
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 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 December 1st, 2009 @ 03:41 PM
- Tag cleared.
I can confirm this as well. It seems to only affect polymorphic associations though?
-
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) }) ...
-
Lee December 3rd, 2009 @ 08:42 PM
This is fixed in rspec-rails with 48e91
http://github.com/dchelimsky/rspec-rails/commit/48e91f62ffe84bc150f...
-
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 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 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 February 21st, 2010 @ 12:45 PM
Is this a rspec-rails or Rails issue? Could someone please provide a failing test case?
-
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 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 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 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 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 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 arespond_to?
along side with themethod_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 June 29th, 2010 @ 06:35 PM
- Milestone set to 2.3.9
-
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 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 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 callsdestroyed?
andmarked_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 bothdestroyed?
andmarked_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 usesflexmock(:model, ModelType)
. -
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 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 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!
-
José Valim October 20th, 2010 @ 01:34 PM
- State changed from needs-more-info to stale
-
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
-
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>