"Overriding" association build methods

Hey everyone

I have (in a nutshell) two models: Customer and Order. Customer
has_many Orders and Order belongs_to Customer. The Order model
contains fields such as name, address and phone that mirror the
associated Customer’s fields at the time the order was placed. The
reason for this is that if the customer changes their details then the
order contains the details that were current when the order was
placed.

I’m looking for a smart way to automatically set these fields when I
create a new Order for a Customer. I would like to create an order
using @order = Customer.orders.build. I could then set each field
manually or even use .build(attributes) but this won’t be DRY when I
need to create orders in the same way in other parts of the site.

So, I’m looking for a way to intercept the build method and initialise
those fields there. Unless someone has another good idea? I had
thought of using ActiveRecord callbacks to do these but there are some
fields (namely delivery address fields) that the customer can edit for
each order but are still initialised from the Customer record.

Thanks
Tristan

On Wed, Oct 7, 2009 at 5:03 AM, Tristan [email protected]
wrote:

each order but are still initialised from the Customer record.

Can’t you do that on the after_save hook?


Leonardo M…
There’s no place like ~

2009/10/7 Tristan [email protected]:

Hey everyone

I have (in a nutshell) two models: Customer and Order. Customer
has_many Orders and Order belongs_to Customer. The Order model
contains fields such as name, address and phone that mirror the
associated Customer’s fields at the time the order was placed. The
reason for this is that if the customer changes their details then the
order contains the details that were current when the order was
placed.

Consider factoring the contact details out into a separate table, with
Customer and Order each has_one contact_info. Then a new order can
use the customer’s current info but if the customer info changes make
a new contact_info record, leaving the old one for the orders.

Colin