如何在FactoryGirl中建立这种模型关联?

时间:2012-02-26 19:58:13

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

我有这个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个角色(现在),每个角色:名称是唯一的。因此,角色数据库包含3个条目,包括now,user,admin,moderator。

如何创建工厂以便我可以创建用户,管理员和管理员及其角色?

我很乐意做类似的事情:

(角色:检查名称的唯一性,因此不应该为每个用户创建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建立关联模型?

3 个答案:

答案 0 :(得分:2)

我联系了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

忘记了“作业”中间表。

答案 1 :(得分:0)

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. 如果您有任何非外键属性,则赋值块也是如此。
  3. 在你的测试中,你可以采取两种方式。

    方式1(自动魔术)

    @assign = FactoryGirl.create(:assign)
    

    方式2(更严格的控制)

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

    然后总是有文档。

答案 2 :(得分:0)

使用: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}