I have some models and have views code that look like the following
class Address < ActiveRecord::Base
belongs_to :customer
end
class Customer < ActiveRecord::Base
has_one :address
has_many :invoices
end
class Invoice < ActiveRecord::Base
belongs_to :customer
end
This code shows a simple invoice structure, with a customer who has a single address.
The view code to display the address lines for the invoice would be as follows:
<%= @invoice.customer.name %>
<%= @invoice.customer.address.street %>
<%= @invoice.customer.address.city %>,
<%= @invoice.customer.address.state %>
<%= @invoice.customer.address.zip_code %>
above view code is not ideal. For proper encapsulation, the
invoice should not reach across the customer object to the street attribute of the
address object. Because if, for example, in the future your application were to change
so that a customer has both a billing address and a shipping address, every place in
your code that reached across these objects to retrieve the street would break and
would need to change. How can I avoid this problem ?
A simples solution would be the customer have a method that will return its main address, like:
If you access its address only by this method, when it has more than one address it is necessary just change the
main_addressmethod to do whatever you want to.Edit 1:
Another option would be use the delegate as suggested by @soundar