19

我有一个标准的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 wiki 页面中每个型号的 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) [...]理论上会为预订创建订单之前运行。

这篇文章建议不要向has_many你的工厂添加关系,但如果有一个好的方法,我还是想解决这个问题。

提前致谢。

4

3 回答 3

36

笏?不可能的?一点也不。

只需将您的代码更改为如下所示:

after :build do |booking, evaluator|
  booking.orders << FactoryGirl.build_list(:order, evaluator.orders_count, booking: nil)
end
于 2013-05-07T01:19:14.380 回答
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
于 2013-12-11T14:05:11.630 回答
0

这似乎是一个过于简单化的观察,但您实际上要做的是确保在Order之前存在Booking,这是不可能的,因为Order没有它就无法存在booking_id(意味着Booking需要首先创建)。

您的工厂中的 has_many 关系没有任何问题,问题在于您的验证。这目前在您的应用程序中有效吗?在这种情况下,您如何保存记录?创建订单和预订的流程是什么?

即使是臭名昭著的accepts_nested_attributes_for人在这里也帮不了你。

我的建议是重新考虑您的记录保存和验证策略,使其更加理智。

于 2012-12-13T18:35:16.030 回答