#spec
let(:price) { create :price,:some_trait,:my_trait }
#factory
FactoryGirl.define do
  factory :price, class: 'Prices::Price' do
    ...
    after(:build) do |p,e|
      # How I can get the traits passed to the create method?
      # => [:some_trait,:my_trait]
      if called_traits_does_not_include(:my_trait) # fake code
        build :price_cost,:order_from, price:p
      end
    end
    ...
  end
end
How I can get the traits which are passed to create in the factory's after(:build) callback?
I don't know of a factory_girl feature which explicitly supports this. But I can think of two partial solutions that might work in specific cases:
Set a transient attribute in the trait:
trait :my_trait do
  using_my_trait
end
factory :price do
  transient do
    using_my_trait false
  end
  after :build do |_, evaluator|
    if evaluator.using_my_trait
      # Do stuff
    end
  end
end
This method requires a transient attribute for each trait that you want to track.
If you don't need to know what traits were used in an after :build callback but you want to track multiple traits without adding a transient attribute for each one, add the trait to a list in an after :build callback in the trait:
trait :my_trait do
  after :build do |_, evaluator|
    evaluator.traits << :my_trait
  end
end
factory :price do
  transient do
    traits []
  end
  before :create do |_, evaluator|
    if evaluator.traits.include? :my_trait
      # Do stuff
    end
  end
end
(Callbacks in traits run before the corresponding callbacks in factories, so if you note a trait in its callback the earliest you can see it is in before :create.) This might be better than the first method if you wanted to track traits in a lot of factories, which would make adding a transient attribute for each trait more painful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With