Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange ActiveRecord::AssociationTypeMismatch

I am getting a very strange error when running a spec:

Failure/Error: entity = Factory.create(:entity, :name => "Test Entity", :creator => user)
 ActiveRecord::AssociationTypeMismatch:
   ::User(#97318850) expected, got User(#92770800)

This is the code that results in the above error. Factory is a factory_girl factory.

  user = Factory(:user, :username => "kai", :email => "[email protected]", :password => "testing")
  entity = Factory.create(:entity, :name => "Test Entity", :creator => user)

When I use :creator => User.first then everything works as expected. I printed out User.first and user, but see no difference.

Any suggestions what the heck is wrong here?

Update

I also got this error when running this simple request spec

describe "Entities" do
  it "should succeed" do
    entity = Factory.create(:entity, :name => "Test Entity 1")
    visit root_path
  end

  it "should also succeed" do
    entity = Factory.create(:entity, :name => "Test Entity 2")
    property = Factory.create(:property, :entity => entity)
  end
end

This time I get

Failure/Error: property = Factory.create(:property, :entity => entity)
 ActiveRecord::AssociationTypeMismatch:
   Entity(#103620190) expected, got Entity(#96047070)

when I delete visit root_path everything works fine (also when running each spec on its own). It just seems to be a problem for request specs. The other specs (model, controller) seems to run fine. I use Capybara 1.0.0.beta1 and RSpec 2.5.

What does this number behind the class name mean?

like image 257
Zardoz Avatar asked May 10 '11 18:05

Zardoz


3 Answers

This is an error that occurs when two different versions of the model have been loaded. I used to hit it in an older version of Rails 3, since the development environment's model reloader was slightly glitched. The numbers after the class name refer to different versions of the class.

It stands to reason that this sort of error might come up in development mode, but it shouldn't in test mode, because, by default, classes are cached. See the config/environments/test.rb file to ensure that cache_classes is set to true.

Also check that you're on the latest version of Rails, 3.0.7. This may be a bug that has since been fixed. While we're at it, check that you're on factory_girl 1.3.3. When using the API totally correctly, which I think you're doing, the only possibilities left are that something is misconfigured or that it's a bug in someone else's code.

like image 77
Matchu Avatar answered Nov 05 '22 18:11

Matchu


Rather than disable class caching, which can be aggravating while in development, the problem might disappear if you get your object fresh before using it. In my case I was loading an object from an association:

desired_object = foo.bar

Finding the item instead removed the problem and didn't require caching classes.

desired_object = Bar.find(foo.bar_id)

I know it isn't ideal, but perhaps this will help someone find out just why it is happening at all.

like image 39
Matt Avatar answered Nov 05 '22 16:11

Matt


For the combination of Rails + Spring + factory_girl this is fixed since version v4.4.1 of factory_girl_rails (Feb 2014) see https://github.com/thoughtbot/factory_girl_rails/pull/121

like image 1
peter_v Avatar answered Nov 05 '22 17:11

peter_v