Overwriting association accesor

Hi,
first of all I would like to wish a happy new year to all the list
members.

Here is my problem. I have a model class where I need to overwrite an
accessor method in order to add some extra behaviour:

class LineItem < ActiveRecord::Base

belongs_to :item, :polymorphic => true

add_item

def item=(item)
write_attribute(:item, item)
self.price = item.price
end

item

def item
read_attribute(:item)
end
end

The problem is that when I overwrite the item= method, the item_id and
item_type attributes aren’t stored in the database when I save the
object so the associated item is missed. I know I could manually set the
item_id and item_type values with something like this:

def item=(item)
write_attribute(:item, item)
self.price = item.price
self.item_id = item.id
self.item_type = item.class.to_s
end

but the problem with this solution resides on that the given item
probably has no id as it should handled as a new record too.
Is there any way I could use the default association behaviour(that is
to automatically set the item_id and item_type attributes and saving the
item first when necessary) and still being able to overwrite the writer
method too? I also tried it by aliasing the item= method but with no
success.

Thanks in advance.


/**

Borja Martín wrote:

Hi,
first of all I would like to wish a happy new year to all the list members.

Thank you Borja.

Here is my problem. I have a model class where I need to overwrite an
accessor method in order to add some extra behaviour:

Look here:
http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/4fe057494c6e23e8


We develop, watch us RoR, in numbers too big to ignore.

Thanks Mark, I solved it by using the alias_method_chain as you
suggested:

class LineItem < ActiveRecord::Base

belongs_to :item, :polymorphic => true

def item_with_price_check=(item)
self.item_without_price_check = item
self.price = item.price
end

alias_method_chain :item=, :price_check

end

Regards

Mark Reginald J.
escribió:> Borja Martín wrote:

Look here: http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/4fe057494c6e23e8


/**

Borja Martín wrote:

Hi,
first of all I would like to wish a happy new year to all the list
members.

Here is my problem. I have a model class where I need to overwrite an
accessor method in order to add some extra behaviour:

class LineItem < ActiveRecord::Base

belongs_to :item, :polymorphic => true

add_item

def item=(item)
write_attribute(:item, item)
self.price = item.price
end

item

def item
read_attribute(:item)
end
end

What you need are association callbacks. The following is from the
ActiveRecord::Association::ClassMethods Page in the RDoc:

Association callbacks

Similiar to the normal callbacks that hook into the lifecycle of an
Active Record object, you can also define callbacks that get trigged
when you add an object to or removing an object from a association
collection. Example:

class Project
has_and_belongs_to_many :developers, :after_add =>
:evaluate_velocity

def evaluate_velocity(developer)
  ...
end

end

It‘s possible to stack callbacks by passing them as an array. Example:

class Project
has_and_belongs_to_many :developers, :after_add =>
[:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
end

Possible callbacks are: before_add, after_add, before_remove and
after_remove.

Should any of the before_add callbacks throw an exception, the object
does not get added to the collection. Same with the before_remove
callbacks, if an exception is thrown the object doesn‘t get removed.