Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FactoryGirl has_many association with validation

I have a standard has_many relationship (Booking has many Orders) with validation that a Booking does not get saved without at least one Order. I'm trying to replicate this with my FactoryGirl factories but the validation is preventing me from doing so.

class Booking < ActiveRecord::Base
  has_many :orders
  validates :orders, presence: true
end

class Order < ActiveRecord::Base
  belongs_to :booking
end

Here are my FactoyGirl factory specifications for each model as followed from FactoryGirl's GitHub wiki page.

FactoryGirl.define do                                                    

  factory :booking do                                                                                                                   
    factory :booking_with_orders do

      ignore do                                                                                                                         
        orders_count 1                                                                                                                  
      end                                                                                                                               

      before(:create) do |booking, evaluator|                                                                                           
        FactoryGirl.create_list(:order, evaluator.orders_count, booking: booking)                                                       
      end                                                                                                                               
    end                                                                                                                                 
  end 

  factory :order do
    booking
  end

end 

When I try to run FactoryGirl.create(:booking_with_orders) from my spec, I get:

Failure/Error: @booking = FactoryGirl.create(:booking_with_orders)
ActiveRecord::RecordInvalid:
  Validation failed: Orders can't be blank

It seems like the check for the validation is running even before before(:create) [...] which would theoretically create the Orders for the Booking.

This post recommends not adding has_many relationships to your factories but I would like to solve this anyways if there is a good way to do it.

Thanks in advance.

like image 670
Erik Nomitch Avatar asked Dec 13 '12 01:12

Erik Nomitch


2 Answers

Wat? Impossible? Not at all.

Just change your code to something like this:

after :build do |booking, evaluator|
  booking.orders << FactoryGirl.build_list(:order, evaluator.orders_count, booking: nil)
end
like image 113
jassa Avatar answered Oct 19 '22 12:10

jassa


Taking off from @jassa's answer, if you just need to add a single (required) associated record with a specific attribute, this pattern worked for me:

factory :booking do
  ignore do
    order_name "name"
  end

  after :build do |factory, evaluator|
    factory.orders << FactoryGirl.build(:order, name: evaluator.order_name, booking: nil)
  end
end
like image 42
Chris Bloom Avatar answered Oct 19 '22 11:10

Chris Bloom