Подтвердить что ты не робот

Странный 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.

Что означает это число за именем класса?

4b9b3361

Ответ 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)

Я знаю, что это не идеально, но, возможно, это поможет кому-то узнать, почему это происходит вообще.

Ответ 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

Надеюсь, это поможет кому-то.