Модель Rails и схема БД с двумя внешними ключами из одной таблицы - PullRequest
2 голосов
/ 03 мая 2010

Я разрабатываю модель заказа для приложения Rails. Я пытаюсь представить заказ, который имеет BillToAddressId и ShipToAddressId в качестве внешних ключей из таблицы адресов.

Таблица адресов ниже:

create_table :addresses do |t|
      t.string :country
      t.string :state
      t.string :city
      t.string :zipcode
      t.string :line1
      t.timestamps

Я новичок в Rails, поэтому я не уверен, как представить это в DB / migrate для Order and Address.

Было бы здорово, если бы кто-нибудь помог мне построить модель и перенести скрипт.

Ответы [ 2 ]

4 голосов
/ 03 мая 2010

Вы можете сделать это следующим образом

class Order < ActiveRecord::Base
  belongs_to :bill_to, :class_name => 'Address', :foreign_key => 'BillToAddressId'
  belongs_to :ship_to, :class_name => 'Address', :foreign_key => 'ShipToAddressId'
end

Для Ruby Naming Conevention Имя столбца «ShipToAddressId» должно быть «ship_to_address_id»

0 голосов
/ 24 апреля 2012

Важно: Вы не должны разрешать пользователям удалять или изменять адреса , учитывая то, как вы моделируете отношения между заказами и адресами. Если вы это сделаете, адреса выставления счетов или доставки в уже выполненных Заказах могут быть изменены или удалены, что очень плохо. Чтобы избежать этого, разрешайте пользователям только добавлять новые адреса или помечать существующие как неактивные.

Учитывая это, вот как вы это сделаете в 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...