FactoryGirl How to add several objects with different roles

cancan, factory-bot, rolify, ruby, ruby-on-rails

Solution

First solution

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

You can then use and combine these traits like this:

# Create a student
create :user, :student

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

Second solution

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

And then:

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

Note that the second solution does not allow you to combine roles as it is. But you could use an array to achieve this.

Problem

``` 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 ``` and my factory ``` 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 ``` I need those mocks receive all roles , but now I can only student role my test with rspec ``` subject(:ability){ Ability.new(user) } let(:user){ nil } context "when is an User" do let(:user) { FactoryGirl.create(:user) } ``` what is happening is this: I can only test with rspec with only 1 paper, but would like to test with all the cancan, I need to create the factory with all these possibilities for different roles

Original source