问题
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.
回答1:
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
回答2:
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
回答3:
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