One-to-one relationship confusion


#1

Hello,

I posted a similar email, earlier in the week, but I still must not be
getting it.

I have a customer that aggregates two addresses; a shipping address
and a billing address. Addresses can also be referenced by other
objects in a similar way, so I would really like to avoid putting the
keys referencing the customer or other objects in the addresses table.
Addresses are exclusively referenced by parent objects and a
many-to-many association is not appropriate.

Ideally I would like the customers table to use a shipping_address_id
and a billing_address_id to reference the aggregate addresses. For
illustration purposes, another object, company might have a
main_address_id, an after_hours_address_id and a weekend_address_id.

In order to keep the keys in the customer table the belongs_to
statements are in the customer model and the has_one statement is in
the address model.

This creates the structure I am after, but not the behavior. The
customer is really the parent object, when I delete the customer I
want it to cascade to addresses, etc.

It seems like I am writing more code than I should to propagate
updates, etc to addresses. Am I totally off base? Any guidance would
be greatly appreciated.

Thanks,
Dan


#2

One solution might be to create a many-to-many relationship for each
type of object that can have an address, but only ever put one address
in the collection. So there would be an address_customer table with
columns address_id, customer_id, and maybe address_type (indicating if
it is billing or shipping). Then you would have tables such as
address_supplier, address_employee, etc.

It’s a little more work up front, but the nice thing is that this would
be very flexible for future changes.

Mike J.


#3

Dan M. wrote:

This creates the structure I am after, but not the behavior. The
customer is really the parent object, when I delete the customer I
want it to cascade to addresses, etc.
You could use a before_destroy callback in the customer for this.

class Customer < ActiveRecord::Base
belongs_to :shipping_address…
belongs_to :billing_address…
before_destroy :clear_addresses
private
def clear_addresses
self.shipping_address.destroy
self.billing_address.destroy
end
end