Anand
Anand

Reputation: 10400

override nested attributes in rails

what happens when I override nested attributes method in rails. For example,

class Order
  has_many :line_items
  accepts_nested_attributes_for :line_items

  def line_item_attributes=(attr)
   # what can I do here.
  end
end

class LineItem
  belongs_to :order
end

In the above code ,

  1. Inside line_item_attributes= method, can I add/modify/delete line items of the order?
  2. When is line_items_attributes= invoked, if I call @order.save(params) ?

Upvotes: 14

Views: 4669

Answers (3)

Weibo Chen
Weibo Chen

Reputation: 379

I met the same problem. Through some effort, I solved the problem. Maybe someone will meet the same question, so I post the answer here.

attr_writer overwrite original setter of line_items Then call super, put the result into default setter

class Order
  attr_writer :line_items
  has_many :line_items
  def line_items=(value)
    # manipulate value
    # then send result to the default setter
    super(result)
  end

Upvotes: 2

Nathan Long
Nathan Long

Reputation: 126042

Use an alias

In Rails 4, you can override and call super.

In earlier versions, you can use Ruby's alias:

class Order
  has_many :line_items
  accepts_nested_attributes_for :line_items

  # order of arguments is new_name, existing_name
  alias :original_line_items_attributes= :line_items_attributes=
  def line_items_attributes=(attrs)
   modified_attributes                 = my_modification_method(attrs)
   self.original_line_items_attributes = modified_attributes
  end

end

Upvotes: 9

Beffa
Beffa

Reputation: 915

  1. Yes you could. Just call

assign_nested_attributes_for_collection_association(:line_items, attributes, mass_assignment_options)

when you're done.

Check the source too: # File activerecord/lib/active_record/nested_attributes.rb, line 263

  1. From the docs:

Saving

All changes to models, including the destruction of those marked for destruction, are saved and destroyed automatically and atomically when the parent model is saved. This happens inside the transaction initiated by the parents save method. See ActiveRecord::AutosaveAssociation.

I don't think it's a good idea to overwrite this method. I would add your code to after_save hook.

Upvotes: 8

Related Questions