ruby-on-rails - FactoryBot has_many 通过关联出现 NoMethodError 'each'

标签 ruby-on-rails ruby-on-rails-5 factory-bot

我有一个工厂,可以在引擎中生成具有角色的设计用户。用户模型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 文档仅建议使用 after(:create) 钩子(Hook)可能是有原因的。从用户评论来看,上述代码存在两个问题:

  • 不使用集合
  • 附加关联时该对象不存在

使用@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 表,这可能是由于命名空间解析造成的问题。

最佳答案

该错误是因为您将角色的单个实例传递给 roles 而不是集合。 FactoryBot无法知道您要创建多少个角色用于关联,因此无论如何都需要手动创建它们。

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

关于ruby-on-rails - FactoryBot has_many 通过关联出现 NoMethodError 'each',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54578789/

相关文章:

ruby-on-rails - Rspec::Matcher 'change' 方法,带有接收器和消息与 block

sql - 如何使用 update_all but every ?有更好的方法吗?

ruby-on-rails - 如何按名称属性对数组类进行排序?

ruby-on-rails - 设计模式和设计原则有什么区别?

ruby-on-rails - ActiveModel::UnknownAttributeError: PaperTrail::VersionAssociation 的未知属性 'foreign_type'

ruby-on-rails - ActiveRecord_Relation 对象的大小

ruby-on-rails - RSpec 无法从 Factorygirl 找到工厂

ruby-on-rails - 是否可以在 Rails 中更改 URL 中的 Controller 名称

ruby-on-rails-5 - 未找到 Rails list 文件(使用 Capistrano 部署)

ruby-on-rails - rspec Controller 测试,预期响应为 <redirect>,但为 <200>