代码之家  ›  专栏  ›  技术社区  ›  Thiago Ribeiro

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

  •  4
  • Thiago Ribeiro  · 技术社区  · 12 年前
    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) } 
    

    现在的情况是:我只能用一张纸来测试rspec,但我想用所有的cancan来测试,我需要为不同的角色创建具有所有这些可能性的工厂

    3 回复  |  直到 12 年前
        1
  •  7
  •   Community Mohan Dere    5 年前

    第一种解决方案

    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
    

    请注意,第二种解决方案不允许您按原样组合角色。但是您可以使用数组来实现这一点。

        2
  •  4
  •   craig.kaminsky    12 年前

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

    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'
    
        3
  •  1
  •   kevin    6 年前

    我的项目中有3个不同的用户: default , merchant , admin .

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

    编辑: 编号的角色使用enum,它根据我定义的数组转换字符串中的数字。有关枚举的详细信息: 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
    
    推荐文章