19

I've been banging my head over this. I want to be able to overwrite attributes on top of traits. I've been reading the documentation and some internet examples but I can't get it to work.

This is sort of what I want to do:

test "..." do 
 #overwrite start_time
 middle = create( :basic_instant_instance, start: 1.hours.ago)
end 

FactoryGirl.define do

  factory :instant_instance do

  trait :active_now do 
    #attributes...
    transient do
      start nil
    end  
    #overwrite start_time
    start_time start.present? ? start : Time.now
  end

  factory :basic_instant_instance,          traits: [:active_now] 
end   

I keep getting:

ArgumentError: Trait not registered: start

Gaston
  • 1,004
  • 1
  • 9
  • 23

1 Answers1

21

You need to rethink your strategy a little here - you have a basic_instant_instance which does not inherit from instant_instance and therefore knows nothing about the trait [:active_now] or start attribute.

You also need to be evaluating the start_time at the time you are building the Factory instance by placing it in curly brackets. Otherwise it will be evaluated before start is initialised.

Try something like the following:

FactoryGirl.define do
  factory :instant_instance do
    trait :active_now do 
      # attributes...

      transient do
        start { nil }
      end

      # overwrite start_time
      start_time { start.present? ? start : Time.now }
    end
  end
end

and then call it like so:

create(:instant_instance, :active_now, start: 1.hours.ago)
Paweł Gościcki
  • 9,066
  • 5
  • 70
  • 81
David
  • 3,510
  • 3
  • 21
  • 39
  • Seems I was wrong about not being able to pass transient data through to a trait - have amended my solution accordingly and also realised you need the curly braces to evaluate correctly – David Oct 24 '16 at 01:25
  • It also works with : create( :basic_instant_instance, start: 1.hours.ago). By the way, I don't understand : "a basic_instant_instance ... does not inherit from instant_instance and therefore knows nothing about the trait [:active_now] or start attribute." – Gaston Oct 24 '16 at 17:54
  • rather than trying to explain it in a comment better if you visit [inheritance](https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#inheritance). I could add further information to my answer if necessary. – David Oct 24 '16 at 18:04
  • and what do you mean it also works with `create( :basic_instant_instance, start: 1.hours.ago)` ... i thought you were getting a `trait not registered error`. – David Oct 24 '16 at 18:05
  • yes, but It seems to have been caused by the curly brackets, as you suggested in your answer :) – Gaston Oct 24 '16 at 18:32