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.
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
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
This seems like an overly simplistic observation but what you're trying to do is in effect make sure that the Order
exists before the Booking
, which is impossible, as the Order
cannot exist without its booking_id
(meaning that the Booking
needs to be created first).
There's nothing wrong with a has_many relationship in your factories, it's your validation that is a problem. Does this currently work in your application? How do you save your records in that case? What is the flow for creating Orders and Bookings?
Even the infamous accepts_nested_attributes_for
won't help you here.
My advice is to rethink your record saving and validation strategy so that it is a little more sane.
来源:https://stackoverflow.com/questions/13851382/factorygirl-has-many-association-with-validation