简体   繁体   中英

accepts_nested_attributes_for, reject_if and has_one relationship not working together?

In my model I have

has_one :order, dependent: :destroy

accepts_nested_attributes_for :order, reject_if: lambda { |order| order[:description].blank? }, allow_destroy: true

For some reason, although the reject_if is tested and returns true (I checked that with the debugger), the nested order is not destroyed.

There is a lot of writing about this phenomenon on the internet, but I can't find a solution.

Does anybody know how to solve this?

I finally created an intelligent "reject_if" setting the destroy flag on this specific occasion, as described in Destroy on blank nested attribute , but, to my own norms, this is not very "ruby", so can't imagine there is no better solution...

accepts_nested_attributes_for :order, allow_destroy: true, reject_if: lambda { |attributes|
  exists = attributes['id'].present?
  empty = attributes[:description].blank?
  attributes.merge!({_destroy: 1}) if exists and empty
  return (!exists and empty)
}

From the nested_attributes API

You may also set a :reject_if proc to silently ignore any new record hashes if they fail to pass your criteria.

params = { member: {
  name: 'joe', order_attributes: [
    { description: 'Kari, the awesome Ruby documentation browser!' },
    { description: 'The egalitarian assumption of the modern citizen' },
    { description: '', _destroy: '1' } # this will be ignored
  ]
}}

Any hash with a blank description will be completly ignored, even if it has the _destroy flag.

If you want to remove records with a blank description, I can think of two solutions

Option 1: remove them with a callback at your model:

before_save :remove_orders_without_description

def remove_orders_without_description
  orders.select{|o| o.description.blank?}.each(&:delete)
end

Option 2: Remove the reject_if option at the model definition and use JS at the view to set the _delete attribute appropriately

尝试这个

accepts_nested_attributes_for :order, reject_if: lambda { |order| order[:_destroy].blank? && order[:description].blank? }, allow_destroy: true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM