NoMethodError“每个”通过协会FactoryBot的has_many

问题描述 投票:1回答:1

我有一个工厂,产生有一项用户W上的发动机内/角色。用户模型has_many :roles through: :roles_users。我能得到的代码与after(:create)条款而与association:关键字工作。

这工作:

应用程序/模型/ myengine / role.rb

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

规格/工厂/ roles.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文档只建议后(:创建)挂钩可能是有原因的。从用户的意见有两个问题与上面的代码:

  • 不使用集合
  • 被附接的关联时,对象不存在

使用角色协会可以直接使用集合,而不是一个对象被分配@Vasfed的建议:

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

按照@ulferts建议,使用新的,而不是创造:

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表,可能是由于命名空间分辨率。

ruby-on-rails ruby-on-rails-5 factory-bot
1个回答
1
投票

这个错误是因为你在角色传递单个实例roles而不是收藏。 FactoryBot没有办法知道你要多少角色创建关联的方式,所以需要手动创建反正。

简单的解决方法无后钩可roles { [ create(:role) ] }

© www.soinside.com 2019 - 2024. All rights reserved.