NoMethodError 'each' на FactoryBot has_many через ассоциацию - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть фабрика, которая генерирует разработанного пользователя с ролями в движке.Модель User has_many :roles through: :roles_users.Я могу заставить код работать с предложением after(:create), но не с ключевым словом association:.

Это работает:

app / model / myengine / role.rb

module MyEngine
    class User < ActiveRecord::Base
        has_many :roles_users
        has_many :roles, through: :roles_users
    end
end

spec / factories / role.rb

factory :role, class: "MyEngine::Role" do
    type: { 'admin' }
end
factory :user, class: "MyEngine::User" do
  sequence(:email) { |n| "tester_#{n}@example.com" }
  password { 'xxx' }
  password_confirmation { 'xxx' }      

  after(:create) do |user|
    user.roles << FactoryBot.create(:role)
  end 
end

Но это не , и тест завершается с undefined method 'each' for #<MyEngine::Role:0x0...> при инициализации:

factory :user, class: "MyEngine::User" do
  sequence(:email) { |n| "tester_#{n}@example.com" }
  password { 'xxx'}
  password_confirmation { 'xxx' }      
  association: :roles, factory: :role
end

Обновлено / отредактировано ниже:

Документ FactoryBot предлагает только возможность после (: create) ловушки по определенной причине.Из комментариев пользователей есть две проблемы с вышеуказанным кодом:

  • не использует коллекцию
  • объект не существует, когда присоединяется ассоциация

Используя предложение @Vasfed, ассоциация ролей может быть назначена непосредственно с использованием коллекции вместо объекта:

factory :user, class: "MyEngine::User" do
  sequence(:email) { |n| "tester_#{n}@example.com" }
  password { 'xxx'}
  password_confirmation { 'xxx' }      
  roles { [ create(:role) ] }
end

Согласно предложению @ulferts использовать new вместо create:

factory :user, class: "MyEngine::User" do
  sequence(:email) { |n| "tester_#{n}@example.com" }
  password { 'xxx'}
  password_confirmation { 'xxx' }      
  roles { [ build(:role) ] }
end

Оба будут выдавать:

ActiveRecord::RecordInvalid: Validation failed: Roles users is invalid

Поскольку модель не имеет проверки, это может указывать на проблему с отсутствующей записью в таблице FK или на невозможность найти таблицу FK, вероятно, из-за разрешения пространства имен.

1 Ответ

0 голосов
/ 07 февраля 2019

Ошибка в том, что вы передаете отдельный экземпляр роли roles вместо коллекции.У FactoryBot нет возможности узнать, сколько ролей вы хотите создать для связи, поэтому их все равно нужно создавать вручную.

Самый простой обходной путь без дополнительных хуков может быть roles { [ create(:role) ] }

...