【问题标题】:How to do this model association in FactoryGirl?FactoryGirl中如何做这个模型关联?
【发布时间】:2012-02-26 19:58:13
【问题描述】:

我有这个 Rails 模型关联(has_many :through)

class User < ActiveRecord::Base
  has_many :assignments
  has_many :roles, :through => :assignments  
end

class Assignment < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
end

class Role < ActiveRecord::Base
  has_many :assignments
  has_many :users, :through => :assignments
end

我的应用程序中只有 3 个角色(目前),每个角色 :name 都是唯一的。所以角色数据库现在包含 3 个条目,用户、管理员、版主。

如何创建工厂以便创建用户、管理员和版主及其角色?

我想做这样的事情:

(角色 :name 已检查唯一性,因此不应为每个用户创建 1 个角色条目,而应为每个用户创建 1 个角色分配。)

# Create my roles
FactoryGirl.create(:role, :name => 'admin')  
FactoryGirl.create(:role, :name => 'user')
FactoryGirl.create(:role, :name => 'moderator')

# Create 10 users and 10 moderators assuming that the username is sequential or something
for i in 0..10
    user = FactoryGirl.create(:user) # user.roles.first.name.eql? 'user' #should be true
    mod = FactoryGirl.create(:moderator)  # mod.roles.first.name.eql? 'moderator' #should be true
end

您将如何创建工厂来模拟与 FactoryGirl 的这种关联?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 testing factory-bot


    【解决方案1】:

    我就这个问题联系了Josh Clayton(Factory Girl的维护者),他很乐意回复如下:

    唯一性约束就是这样做的地方 - 遗憾的是,您必须在循环之外创建角色,命名它们并重用这些名称。可能有其他方法可以绕过它,但我不确定你是否以及如何去做。

    所以最后我通过以下方式解决了这个问题:

         user_role = FactoryGirl.create(:role, :title => 'user')
    
         for i in (1..10) do
           user = FactoryGirl.create(:user)
           user.roles << user_role 
         end
    

    刚刚忘记了“赋值”中间表。

    【讨论】:

      【解决方案2】:
      FactoryGirl.define do
        factory :user do
          col1 { Forgery(basic).col1_datatype }
        end
        factory :role do
          another_attribute { Forgery(basic).another_attr_datatype }
        end
        factory :assignment do
          user
          role
        end
      end
      

      几件事

      1. 确保在用户和角色块内添加任何有助于满足验证的列。
      2. 如果您有任何非外键属性,分配块也是如此。

      在您的测试中,您可以采用两种方式。

      方式 1(自动魔法)

      @assign = FactoryGirl.create(:assign)
      

      方式 2(更严格的控制)

      @user = FactoryGirl.create(:user)
      @role = FactoryGirl.create(:role)
      @assign = FactoryGirl.create(:assign, user: @user, role: @role)
      

      然后总是有文档。

      【讨论】:

      • 当你告诉我“确保在用户和角色块中添加任何有助于满足验证的列”时,你是什么意思。 .您还可以实际修复您的代码以符合我在问题中提到的示例吗?科尔1?另一个属性? ,谢谢:)
      【解决方案3】:

      使用:class:parent 选项进行工厂定义。

      Factory.define :user, :class => User do |u|
        u.role 'user'
      end
      
      Factory.define :moderator, :parent => :user do |m|
        m.role 'modelrator'
      end
      

      所以在你的规格中:

        10.times{ Factory :user}
        9000.times{ Factory :moderator}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多