FactoryGirl如何添加具有不同角色的多个对象

时间:2014-02-13 22:14:33

标签: ruby-on-rails ruby factory-bot cancan rolify

class Ability

include CanCan::Ability

def initialize(user)

user ||= User.new # guest user

if user.has_role?  :student
  can :create, Atendimento
end

if user.has_role?  :professor
  can :create, Atendimento
end
if user.has_role? :administrative
  can [:read, :create], [Atendimento]
  can [:edit, :update], Atendimento
  can :manage, [Type, Place]
 end
if user.has_role? :admin
  can :manage, :all
end
end
end

和我的工厂

FactoryGirl.define do
factory :user do |f|
f.name "Alessandro"
f.username "alessandrocb"
f.matricula "123456789"
f.password "123456789"
f.password_confirmation "123456789"
f.after(:create) {|user| user.add_role(:student)}
end

我需要那些模拟获得所有角色,但现在我只能学生角色

我的rspec测试

subject(:ability){ Ability.new(user) }
let(:user){ nil }

 context "when is an User" do
 let(:user) { FactoryGirl.create(:user) } 

发生的事情是:我只能用只有1张纸的rspec进行测试,但是想用所有的cancan进行测试,我需要为不同的角色创建具有所有这些可能性的工厂

3 个答案:

答案 0 :(得分:6)

第一个解决方案

FactoryGirl.define do
  factory :user do
    name "Alessandro"
    username "alessandrocb"
    (...)
    trait :student do
      after(:create) {|user| user.add_role(:student)}
    end
    trait :professor do
      after(:create) {|user| user.add_role(:professor)}
    end
    trait :administrative do
      after(:create) {|user| user.add_role(:administrative)}
    end
    trait :admin do
      after(:create) {|user| user.add_role(:admin)}
    end
  end
end

然后您可以使用和组合这些特征:

# Create a student
create :user, :student

# Create a user who is both professor and admin
create :user, :professor, :admin

第二种解决方案

FactoryGirl.define do
  factory :user do
    name "Alessandro"
    username "alessandrocb"
    (...)
    ignore do
      role
    end
    after(:create) do |user, params|      
      user.add_role(params.role)  if params.role
    end
  end
end

然后:

# Create a student
create :user, role: :student

请注意,第二个解决方案不允许您按原样组合角色。但您可以使用数组来实现此目的。

答案 1 :(得分:2)

我最近遇到了类似的问题。这是我的用户工厂:

FactoryGirl.define do

  sequence :email do |n|
    "user#{n}@example.com"
  end

  factory :user do
    email
    password 'password'

    factory :admin_user do
      role 'administrator'
    end

    factory :support_user do
      role 'support'
    end

    factory :editor_user do
      role 'editor'
    end

    factory :sales_user do
      role 'sales'
    end

    factory :author_user do
      role 'author'
    end

    factory :guest_user do
      role 'guest'
    end

  end

end

从那里我可以打电话给相关工厂查看规格:

create(:editor_user)

或者,根据您的用户模型及其附属属性,您还可以构建如下工厂:

create(:user, role: 'guest') # my User model has a properly called 'role'

答案 2 :(得分:1)

我的项目中有3个不同的用户:defaultmerchantadmin

我有一个处理条件的文件。注意:这是FactoryBot,特别是工厂bot导轨。我也在使用宝石Faker。

编辑:带编号的角色使用枚举,该枚举根据我定义的数组将数字转换为字符串。有关枚举的更多信息:https://naturaily.com/blog/ruby-on-rails-enum

工厂/user.rb

// factories/user.rb
FactoryBot.define do
  factory :user do
    name  { Faker::Name.first_name }
    street_address { Faker::Address.street_address }
    city { Faker::Address.city }
    state { Faker::Address.state }
    zip { Faker::Address.zip }
    email { Faker::Internet.email }
    password { Faker::Internet.password }
    trait :default_user do
      role { 0 }
    end
    trait :admin_user do
      role { 1 }
    end
    trait :merchant_user do
      role { 2 }
    end
  end
end

规格文件

// a spec file
RSpec.describe 'User logging in' do
  let(:user) { create(:user, :default_user) }
  let(:admin) { create(:user, :admin_user) }
[...]
end