Я думаю, вы смешиваете то, что должно быть в миграции, и что должно быть в модели (и я не имею в виду это в отрывочном смысле, поэтому, пожалуйста, не принимайте это так).
я сколотить рельсы 5 проекта для вас, чтобы продемонстрировать то, что я думаю, что вы хотите достичь:
В целом я считаю, что вы хотите иметь и погрузочно-разгрузочные станции, хранящиеся в одной таблице, но ссылаются на них отдельно как атрибуты порядка.Другими словами, вы ищете однонаправленное наследование.
Это то, что я построил быстро:
# app/models/order.rb
class Order < ApplicationRecord
belongs_to :loading_station, optional: true
belongs_to :unloading_station, optional: true
end
# app/models/station.rb
class Station < ApplicationRecord
end
# app/models/loading_station.rb
class LoadingStation < Station
has_many :orders
end
# app/models/unloading_station.rb
class UnloadingStation < Station
has_many :orders
end
Как вы можете видеть модели LoadingStation
и UnloadingStation
наследуют Station
модель. Модель Station
получает таблицу в базе данных.
# db/migrate/20170826085833_create_orders.rb
class CreateStations < ActiveRecord::Migration[5.1]
def change
create_table :stations do |t|
t.string :comp_name1
t.string :street
t.string :street_num
t.string :zip_code
t.string :city
t.string :type, null: false
t.timestamps
end
end
end
Столбец типа определяется как :string
и содержит имя класса из подклассов моделей, либо LoadingStation
или UnloadingStation
.
И миграции заказов таблица выглядит следующим образом:
# db/migrate/20170826085833_create_orders.rb
class CreateOrders < ActiveRecord::Migration[5.1]
def change
create_table :orders do |t|
t.belongs_to :loading_station, null: true, index: true
t.belongs_to :unloading_station, null: true, index: true
t.string :status
end
end
end
Как вы можете видеть, что ссылается на LoadingStation.id
и UnloadingStation.id
. Я не был уверен, были ли эти атрибуты обязательными, поэтому я установил их в null: false
в определениях столбцов и optional: true
в модели Order
.
Чтобы проверить, что это работает, я создал один Загрузочные, один UnloadingStation и один заказ семян базы данных:
# db/seeds.rb
loading_station_1 = LoadingStation.create!(
comp_name1: "Loading Station 1",
street: "Park Ave",
street_num: "300",
zip_code: 10001,
city: "NY"
)
unloading_station_4 = UnloadingStation.create!(
comp_name1: "Unloading Station 4",
street: "Madison Ave",
street_num: "204",
zip_code: 10001,
city: "NY"
)
Order.create!(
loading_station: loading_station_1,
unloading_station: unloading_station_4,
status: "delivered"
)
Чтобы проверить все это, просто создать базу данных, запустить миграцию и выполнить семена:
rails db:create
rails db:migrate
rails db:seed
Чтобы проверить результат вживую открыть rails console
:
irb(main):001:0> pp Station.all
Station Load (0.3ms) SELECT "stations".* FROM "stations"
[#<LoadingStation:0x007fcb8ac39440
id: 1,
comp_name1: "Loading Station 1",
street: "Park Ave",
street_num: "300",
zip_code: "10001",
city: "NY",
type: "LoadingStation",
created_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00,
updated_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00>,
#<UnloadingStation:0x007fcb8ac39288
id: 2,
comp_name1: "Unloading Station 4",
street: "Madison Ave",
street_num: "204",
zip_code: "10001",
city: "NY",
type: "UnloadingStation",
created_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00,
updated_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00>]
irb(main):002:0> pp Order.all
Order Load (0.2ms) SELECT "orders".* FROM "orders"
[#<Order:0x007fcb8bca2700
id: 1,
loading_station_id: 1,
unloading_station_id: 2,
status: "delivered">]
irb(main):003:0> order = Order.first
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Order id: 1, loading_station_id: 1, unloading_station_id: 2, status: "delivered">
irb(main):004:0> pp order.loading_station
LoadingStation Load (0.2ms) SELECT "stations".* FROM "stations" WHERE "stations"."type" IN ('LoadingStation') AND "stations"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
#<LoadingStation:0x007fcb8c0e4390
id: 1,
comp_name1: "Loading Station 1",
street: "Park Ave",
street_num: "300",
zip_code: "10001",
city: "NY",
type: "LoadingStation",
created_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00,
updated_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00>
irb(main):005:0> pp order.unloading_station
UnloadingStation Load (0.3ms) SELECT "stations".* FROM "stations" WHERE "stations"."type" IN ('UnloadingStation') AND "stations"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
#<UnloadingStation:0x007fcb8a36a378
id: 2,
comp_name1: "Unloading Station 4",
street: "Madison Ave",
street_num: "204",
zip_code: "10001",
city: "NY",
type: "UnloadingStation",
created_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00,
updated_at: Sat, 26 Aug 2017 09:06:53 UTC +00:00>
irb(main):006:0> pp order.status
"delivered"
Надеюсь, это поможет вам. Я проверил код в github, вы можете получить доступ к нему по адресу https://github.com/JurgenJocubeit/SO-41796815.
Как выглядит ваша модель 'Order'? У вас на самом деле определена ассоциация 'unloading_station'? – usha