Rails reject_if和验证无效:没有嵌套对象时无法保存

时间:2014-06-19 11:30:36

标签: validation activerecord ruby-on-rails-4 nested-attributes

我有这两个模型

class Transaction < ActiveRecord::Base
  has_many :order, :inverse_of => :transaction, :dependent => :destroy
  accepts_nested_attributes_for :order, :allow_destroy=> true, :reject_if=> :menu_id_validation
  def menu_id_validation(attributes)
    attributes['menu_id'].blank?
  end
end

class Order < ActiveRecord::Base
  belongs_to :transaction, :inverse_of => :order
  belongs_to :menu
  validates :menu_id, :presence => true
  validates_presence_of :transaction
end

当我发送这样的参数来创建交易时:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"...",
"transaction"=>{..., "customer_id"=>"30", "staff_id"=>"8", 
"order_attributes"=>{"0"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"1"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"2"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"},
"3"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}}},
"commit"=>"save”}

我希望:reject_if丢弃所有的订单参数,因为它们都没有'menu_id',实际上:menu_id_validation为它们返回true。 但是,我无法保存这个并获得订单模型的验证错误:menu。

非常奇怪的是,我可以通过填写至少一个订单参数来保存:menu_id。 如果我使用某个订单模型对象保存事务模型对象,我可以像这样删除所有这些。

Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", 
"transaction"=>{...,"customer_id"=>"10", "staff_id"=>"8",
"order_attributes"=>{"0"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"true", "id"=>"219"}, 
"1"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"2"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"3"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}},},
"commit"=>"save", "id"=>"108"}

第一个参数已保存在db中,并将被“_destroy”=&gt; true删除。这样,所有嵌套订单模型对象都被删除了。但是这可以保存。

我认为这个问题是由订单验证和reject_if之间的冲突(?)引起的。 即使尚未保存事务模型对象并且没有订单模型对象,我该怎么做才能保存事务模型对象?

1 个答案:

答案 0 :(得分:0)

我认为:reject_if只会在相关模型(在本例中为Order)中使用方法的名称,例如:new_record?或proc,作用于嵌套属性哈希,如proc {|attrs| attrs['menu_id'].blank? }。 所以你要么想要使用proc(一个好主意,因为你的条件似乎只有一行),要么在:menu_id_validation模型中而不是在Order内定义Transaction。< / p>