Is this a relationship that can be described in Ruby on Rails' ActiveRecord model relationships?
Customer Address
=================== =========
Billing_Address_Id >------}
}---|- AddressId
Shipping_Address_Id >------}
So that I could have data that looks like this:
Address:
Id | Addr | City | State | Zip |
================================================
1 | 123 Main | New York | NY | 99999 |
2 | 200 2nd Street | New York | NY | 99999 |
3 | 300 3rd Street | Albany | NY | 99998 |
4 | PO Box 4 | Albany | NY | 99998 |
Customer:
Id | Name | Billing_Address_Id | Shipping_Address_Id |
=======================================================
1 | Bob | 1 | 1 |
2 | Al | 2 | 1 |
3 | Joe | 3 | 4 |
I want to store addresses in their own table because the data may be shared across customers (shipping address especially). But there would only even be two addresses for any given customer.
I'd like to avoid a many-to-many relationship unless there is no other way.
Yes, it's perfectly possible to do that. Given a customers
table with the two foreign keys shipping_address_id
and billing_address_id
to the addresses
table, your Customer
model could look like this:
class Customer < ActiveRecord::Base
belongs_to :billing_address, :class_name => 'Address'
belongs_to :shipping_address, :class_name => 'Address'
end
This will let a customer reference the same address row for shipping and billing addresses, and will also let several customers share addresses.
Update: When sharing references to addresses like this you'll probably want to carefully consider how to handle address updates. In your example, Bob and Al share the same shipping address. Now, if Bob updates his shipping address you probably want to create a new Address
record for Bob's new address rather than update the existing record, to avoid changing Al's address too. Sometimes, you actually might want to update both customers' addresses in this situation, but in most cases you probably don't.
Given table definitions like this:
create_table :addresses do |t|
t.string :street
t.string :city
t.string :state
t.string :zip
t.timestamps
end
create_table :customers do |t|
t.string :name
t.references :shipping_address
t.references :billing_address
t.timestamps
end
You can associate a billing and shipping address with your customer like this:
class Customer < ActiveRecord::Base
belongs_to :shipping_address, :class_name => "Address"
belongs_to :billing_address, :class_name => "Address"
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With