Question

In my application I am using mark_for_destruction to remove nested records on the basis of condition.

I have a Ticket model and a Pick model:

class Ticket < ActiveRecord::Base
  has_many :picks
  accepts_nested_attributes_for :picks
  attr_accessible :picks_attributes

  before_save :mark_destroy_zero_weighted_picks

  def mark_destroy_zero_weighted_picks
    picks.each do |pick|
      pick.mark_for_destruction if pick.weight.to_i == 0
    end
  end
end

class Pick < ActiveRecord::Base
  belongs_to :ticket
  attr_accessible :ticket_id
  attr_accessible :weight
end    

If there is a ticket with 4 picks associated to it, having weight 1,0,2,1; then only the first pick gets saved and all other picks after the 0 weighted pick (for which marked_for_destruction is true) are removed when creating a new ticket record. It works fine if I edit the record but does not work while creating a new record.

Was it helpful?

Solution

It looks to me like there was a bug in rails 3.2.3 - I don't see this problem with 3.2.12 but I'm not sure when it got fixed.

That said, an easier way to approach this may be to use the reject_if option for accepts_nested_attributes_for:

class Ticket < ActiveRecord::Base
  has_many :picks
  accepts_nested_attributes_for :picks,
    :reject_if => lambda { |attributes| attributes[:weight].to_i == 0 },
    :allow_destroy => true
  attr_accessible :picks_attributes
end

This will silently reject all new picks that have a weight of 0. The only thing it doesn't address is the update case if you want existing picks to be deleted when they are updated to have a weight of 0, but you have a remove pick link to allow for that anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top