Ruby on rails 命名错误';每个';在FactoryBot上,通过关联有许多

Ruby on rails 命名错误';每个';在FactoryBot上,通过关联有许多,ruby-on-rails,ruby-on-rails-5,factory-bot,Ruby On Rails,Ruby On Rails 5,Factory Bot,我有一个工厂,它在引擎中生成具有角色的Desive用户。用户模型有许多:角色到::角色\u用户。我可以让代码在(:create)子句之后使用,但不能使用关联:关键字 这项工作: app/model/myengine/role.rb module MyEngine class User < ActiveRecord::Base has_many :roles_users has_many :roles, through: :roles_users

我有一个工厂,它在引擎中生成具有角色的Desive用户。用户模型
有许多:角色到::角色\u用户
。我可以让代码在(:create)子句之后使用
,但不能使用
关联:
关键字

这项工作:

app/model/myengine/role.rb

module MyEngine
    class User < ActiveRecord::Base
        has_many :roles_users
        has_many :roles, through: :roles_users
    end
end
更新/编辑如下:

FactoryBot文档只是出于某种原因建议使用after(: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的建议,使用新建而不是创建:

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

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


没有后钩子的最简单的解决方法是
角色{[create(:role)]}

谢谢您的建议。这绝对有道理。尝试这种方法时,我遇到了一个针对through表的验证错误。不过,实例化空集合是可行的:角色{[]}。我将展开我的问题以反映这一点。
roles{[create(:role)]}
将尝试立即创建角色,甚至在创建用户之前。请尝试
roles{[build(:role)]}
。它也更通用,并且支持出于性能原因实际上不想保存模型的场景。@ulferts:谢谢您指出这一点。当时不存在的对象是有意义的。我仍然会遇到同样的错误,但现在我可以指出FK表的一个问题(该表必须具有该对象的id,该对象尚未创建)
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