#ruby-on-rails #ruby
#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.first
и user
, но не вижу разницы.
Любые предложения, что, черт возьми, здесь не так?
Обновить
Я также получил эту ошибку при запуске этой простой спецификации запроса
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, что, я думаю, вы делаете, остаются единственные возможности, что что-то неправильно настроено или что это ошибка в чужом коде.
Комментарии:
1. Действительно, я
cache_classes
установил значение false (причина некоторых старых проблем со spork … что в то же время, похоже, больше не вызывает проблем). Теперь все работает нормально. Большое спасибо за вашу помощь.2. 1 — Спасибо! Мне это тоже помогло! Задавался вопросом, что, черт возьми, это было!
3. Я также иногда вижу это, когда запускаю spork с cache_classes, установленным в false, чтобы я мог быстро запускать rspec… Я не нашел способа обойти это, кроме запуска спецификаций без spork.
4. Работа с базовым приложением во внешнем интерфейсе (и никогда не перезапускающим сервер) В итоге я столкнулся с этой ошибкой, также решаемой с перезапуском сервера, спасибо!
5. У меня была такая же проблема в консоли после использования
reload!
. Выход и запуск консоли решили проблему. Поэтомуreload!
также возникают некоторые проблемы с кэшированием классов. (С использованием rails 4)
Ответ №2:
Вместо того, чтобы отключать кэширование классов, что может усугублять ситуацию во время разработки, проблема может исчезнуть, если вы обновите свой объект перед его использованием. В моем случае я загружал объект из ассоциации:
desired_object = foo.bar
Поиск элемента вместо этого устранил проблему и не требовал кэширования классов.
desired_object = Bar.find(foo.bar_id)
Я знаю, что это не идеально, но, возможно, это поможет кому-то выяснить, почему это вообще происходит.
Комментарии:
1. Я взломал это, вызвав
.reload
объект после ассоциации, как вfoo.bar.reload
Ответ №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:
Проблема для меня заключалась в определении моей фабрики, где я использовал дополнительные фабрики для заполнения полей идентификатора. Я случайно сослался на атрибут, которого не существовало в таблице (account вместо 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
Надеюсь, это кому-то поможет.