eeeeeean eeeeeean - 7 months ago 16
Ruby Question

Defining factories with chained associations

I want to create a

:membership
factory and then create a
:comment
factory that in this specific case "rolls up" to the same Group that the Membership does. It shouldn't always point to the same Group, so I'm defining my factories like this:

factory :membership do
user
group
end

factory :decision do
group
end

factory :comment do
decision
end


And then I'm creating those two objects like this:

membership = create(:membership)
decision = create(:decision, group: membership.group)
comment = create(:comment, decision: decision)


This works, but it's a minimal example. I'd like to be able to create the Membership and then pass the Membership as an argument to the Comment constructor, making the second line unnecessary. I've had a look at the factory_girl docs and I can't figure out how to change my factory definitions to do this. Is there a way?

Answer

Pass the Membership to the Comment factory in a transient attribute. In a before(:create) callback, create a Decision from the Membership and add the Decision to the Comment:

factory :comment do
  transient do
    membership
  end

  before(:create) do |comment, evaluator|
    decision = create(:decision, group: evaluator.membership.group)
    comment.decision = decision
  end

end