我有一个标准has_many
关系(预订有很多订单),验证如果没有至少一个订单,预订就不会被保存。我试图用FactoryGirl工厂复制这个,但验证阻止我这样做。
class Booking < ActiveRecord::Base
has_many :orders
validates :orders, presence: true
end
class Order < ActiveRecord::Base
belongs_to :booking
end
以下是FactoryGirl的GitHub维基页面中每个型号的FactoyGirl工厂规格。
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
当我尝试从我的规范中运行FactoryGirl.create(:booking_with_orders)
时,我得到:
Failure/Error: @booking = FactoryGirl.create(:booking_with_orders)
ActiveRecord::RecordInvalid:
Validation failed: Orders can't be blank
似乎验证检查甚至在before(:create) [...]
之前就已经开始了,这在理论上会创建预订订单。
This post建议不要将has_many
关系添加到您的工厂,但如果有一个好的方法,我想解决这个问题。
提前致谢。
答案 0 :(得分:31)
笏?不可能?完全没有。
只需将您的代码更改为以下内容:
after :build do |booking, evaluator|
booking.orders << FactoryGirl.build_list(:order, evaluator.orders_count, booking: nil)
end
答案 1 :(得分:2)
从@ jassa的答案中解脱,如果您只需要添加一个具有特定属性的单个(必需)关联记录,这种模式对我有用:
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
答案 2 :(得分:0)
这似乎是一种过于简单化的观察,但你要做的是确保Order
存在于Booking
之前,这是不可能的,因为Order
没有booking_id
就不能存在(意味着需要先创建Booking
)。
你的工厂中的has_many关系没有任何问题,这是你的验证,这是一个问题。这目前适用于您的应用程序吗?在这种情况下,你如何保存你的记录?创建订单和预订的流程是什么?
即使臭名昭着的accepts_nested_attributes_for
也不会帮助你。
我的建议是重新考虑您的记录保存和验证策略,以使其更加清晰。