奇怪的ActiveRecord :: AssociationTypeMismatch

时间:2011-05-10 18:31:13

标签: ruby-on-rails ruby

运行规范时出现了一个非常奇怪的错误:

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

这是导致上述错误的代码。工厂是factory_girl工厂。

  user = Factory(:user, :username => "kai", :email => "xxx@yyy.com", :password => "testing")
  entity = Factory.create(:entity, :name => "Test Entity", :creator => user)

当我使用:creator => User.first时,一切都按预期工作。我打印出User.firstuser,但没有看到差异。

有什么建议这里有什么问题吗?

更新

运行这个简单的请求规范时,我也遇到了这个错误

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

这次我

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

当我删除visit root_path时,一切正常(也是在自己运行每个规范时)。这似乎是请求规范的问题。其他规格(型号,控制器)似乎运行良好。我使用Capybara 1.0.0.beta1和RSpec 2.5。

这个数字背后的数字是什么意思?

5 个答案:

答案 0 :(得分:55)

这是在加载了两个不同版本的模型时发生的错误。我曾经在较旧版本的Rails 3中使用它,因为开发环境的模型重新加载器略微出现了问题。类名后面的数字指的是该类的不同版本。

理所当然,这种错误可能会在开发模式中出现,但它不应该在测试模式下,因为默认情况下会缓存类。请参阅config/environments/test.rb文件以确保cache_classes设置为true。

另请检查您使用的是最新版本的Rails 3.0.7。这可能是一个已修复的错误。当我们在这时,检查你是否在factory_girl 1.3.3。当我完全正确地使用API​​时,我认为你正在做的事情,剩下的唯一可能性是某些东西配置错误或者是别人代码中的错误。

答案 1 :(得分:5)

如果在使用之前让对象保持新鲜状态,问题可能会消失,而不是禁用在开发过程中可能会加重的类缓存。在我的情况下,我正在从一个协会加载一个对象:

desired_object = foo.bar

找到项目而不是删除问题,并且不需要缓存类。

desired_object = Bar.find(foo.bar_id)

我知道这不太理想,但也许这会帮助别人找出它为什么会发生这种情况。

答案 2 :(得分:1)

对于Rails + Spring + factory_girl的组合,这是修复的,因为factory_girl_rails的版本v4.4.1(2014年2月)见https://github.com/thoughtbot/factory_girl_rails/pull/121

答案 3 :(得分:0)

如果您使用 Spring 或任何其他 Rails应用程序预加载器,可能会发生类似错误,请确保重新启动它。

spring stop
spring start
# or usually bin/rails s or bin/rails c for console

答案 4 :(得分:0)

我的问题是在我的工厂定义中,我使用其他工厂来填充id字段。我不小心提到了表中不存在的属性(帐户,而不是account_id)。见下面的例子。

factory Omni::CustomerAccount do
  sequence(:display_name) {|n| "test #{n}"}
  customer_id :customer  # this is correct
  account :account  # wrong - this should say account_id :account
end

希望这有助于某人。