Важно: Вы не должны разрешать пользователям удалять или изменять адреса , учитывая то, как вы моделируете отношения между заказами и адресами. Если вы это сделаете, адреса выставления счетов или доставки в уже выполненных Заказах могут быть изменены или удалены, что очень плохо. Чтобы избежать этого, разрешайте пользователям только добавлять новые адреса или помечать существующие как неактивные.
Учитывая это, вот как вы это сделаете в Rails (то есть делайте то, что вы сказали, а не то, что я обрисовал в параграфе выше):
Миграции
class CreateOrders < ActiveRecord::Migration
create_table :orders do |t|
def up
t.references :billing_address
t.references :shipping_address
end
end
end
Здесь вы указываете, что в этой таблице есть два столбца, которые будут называться: billing_address и: shipping_address и которые содержат ссылки на другую таблицу. Rails фактически создаст для вас столбцы с именами 'billing_address_id' и 'shipping_address_id'. В нашем случае они будут ссылаться на строки в таблице Users, но мы указываем это в моделях, а не в миграциях.
Модель
class Order < ActiveRecord::Base
belongs_to :billing_address, class_name => 'Address'
belongs_to :shipping_address, class_name => 'Address'
end
Здесь вы создаете свойство в модели Order с именем: billing_address, а затем указываете, что это свойство будет ссылаться на экземпляр класса Address. Rails, увидев «own_to», будет искать столбец в таблице заказов с именем «billing_address_id», который мы определили выше, и использовать его для хранения внешнего ключа. Затем вы делаете то же самое для адреса доставки.
Это позволит вам получить доступ к вашему адресу выставления счета и адресу доставки, как экземплярам модели адреса, через экземпляр модели заказа, например:
@order.billing_address # Returns an instance of the Address model
@order.shipping_address.street1 # Returns a string, as you would expect
В качестве дополнительного примечания: в данном случае номенклатура «принадлежат к кому-то» немного сбивает с толку, так как Орден не принадлежит адресу. Не обращайте внимания на вашу интуицию, хотя; «own_to» используется в зависимости от того, что содержит внешний ключ.
class Address < ActiveRecord::Base
has_many :orders_as_billing_address, :class_name => 'Order', :foreign_key => 'billing_address_id'
has_many :orders_as_shipping_address, :class_name => 'Order', :foreign_key => 'shipping_address_id'
end
Здесь вы создаете свойство в модели адресов с именем orders_as_billing_address, определяя, что это свойство связано с моделью заказов и что внешний ключ в модели заказов, который связывает его с этим свойством, называется 'billing_address_id'. Затем вы делаете то же самое для: orders_as_shipping_address.
Это позволяет вам получить все заказы, в которых адрес использовался в качестве адреса для выставления счета или доставки, например:
@address.orders_as_billing_address
@address.orders_as_shipping_address
Выполнение любого из них вернет массив экземпляров модели Order.