Странный ActiveRecord:: AssociationTypeMismatch
Я получаю очень странную ошибку при запуске spec:
Failure/Error: entity = Factory.create(:entity, :name => "Test Entity", :creator => user)
ActiveRecord::AssociationTypeMismatch:
::User(#97318850) expected, got User(#92770800)
Это код, который приводит к вышеуказанной ошибке. Factory - factory_girl factory.
user = Factory(:user, :username => "kai", :email => "[email protected]", :password => "testing")
entity = Factory.create(:entity, :name => "Test Entity", :creator => user)
Когда я использую :creator => User.first
, тогда все работает так, как ожидалось. Я распечатал User.first
и user
, но не вижу разницы.
Какие-нибудь предложения о том, что здесь не так?
Update
Я также получил эту ошибку при запуске этой простой спецификации запроса
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.
Что означает это число за именем класса?
Ответы
Ответ 1
Это ошибка, возникающая при загрузке двух разных версий модели. Раньше я использовал его в более ранней версии Rails 3, так как перегружатель модели среды разработки немного сбился. Числа после имени класса относятся к разным версиям класса.
Понятно, что такая ошибка может возникнуть в режиме разработки, но она не должна работать в тестовом режиме, потому что по умолчанию классы кэшируются. См. Файл config/environments/test.rb
, чтобы убедиться, что для параметра cache_classes
установлено значение true.
Также проверьте, что вы используете последнюю версию Rails, 3.0.7. Это может быть ошибка, которая с тех пор была исправлена. Пока мы на нем, убедитесь, что вы находитесь на factory_girl 1.3.3. При правильном использовании API, который, как я думаю, вы делаете, остается только, что что-то неправильно сконфигурировано или что это ошибка в коде другого пользователя.
Ответ 2
Вместо того, чтобы отключать кэширование классов, которые могут ухудшаться во время разработки, проблема может исчезнуть, если вы снова получите свой объект перед его использованием. В моем случае я загружал объект из ассоциации:
desired_object = foo.bar
Поиск элемента вместо этого устраняет проблему и не требует кэширования классов.
desired_object = Bar.find(foo.bar_id)
Я знаю, что это не идеально, но, возможно, это поможет кому-то узнать, почему это происходит вообще.
Ответ 3
Для комбинации Rails + Spring + factory_girl это исправлено, так как версия v4.4.1 factory_girl_rails (февраль 2014) см. https://github.com/thoughtbot/factory_girl_rails/pull/121
Ответ 4
Аналогичная ошибка может возникнуть, если вы используете Spring или любой другой предварительный загрузчик приложений Rails, убедитесь, что вы перезапустили его.
spring stop
spring start
# or usually bin/rails s or bin/rails c for console
Ответ 5
Проблема для меня была в моем определении factory, где я использовал дополнительные заводы для заполнения полей 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
Надеюсь, это поможет кому-то.