将一个表上的列引用到另一个表上的列



我正在阅读另一个问题,关于从两个单独的表引用列,但有点困惑,如果它解决了我的问题。我有两张桌子,目的地和预订。目的地表有一个列用于location_id,预订有一个列用于位置,我试图从目的地表中的location_id列引用预订表中的位置。

这是我预订(迁移)的表格

class CreateBookings < ActiveRecord::Migration[6.1]
def change
create_table :bookings do |t|
t.string :name
t.string :start_date
t.string :end_date
t.string :email
t.integer :location
t.timestamps
end
end

end

,这是我的表(迁移)为目的地

class CreateDestinations < ActiveRecord::Migration[6.1]
def change
create_table :destinations do |t|
t.string :address
t.string :city
t.string :state
t.string :zip
t.integer :location_id
t.timestamps
end
end
end

我的模型当前设置为

class Booking < ApplicationRecord
# belongs_to :reservation, optional: true
has_many :destinations, :class_name => 'Destination', :foreign_key=> 'location_id'
validates :name, :start_date, :end_date, :email, presence: true
end

and 
class Destination < ApplicationRecord
has_many :bookings,  :class_name => 'Booking', :foreign_key=> 'location'
end

我当前引用的列正确,还是有别的东西我应该做吗?

您应该如何编写迁移取决于您的模型之间的关联。外键用于具有belongs_to关联的表。

一次预订可以有多个目的地吗?如果答案是否定的,您需要将预订模型中的关联更改为belongs_to :destination,然后在预订表中添加:destination_id(如果您愿意,您可以给它一个自定义名称,如:location_id,但惯例是使用模型名称)。

如果一个预订可以有多个目的地,而一个目的地肯定可以有多个预订,那么你就有了一个多对多关系。在这种情况下,您不会将外键放在目的地表中,也不会将外键放在预订表中。相反,您需要在它们之间建立一个连接表,这就是外键所在的位置。

Rails提供了两种不同的方式来声明多对多关系。看到https://guides.rubyonrails.org/association_basics.html choosing-between-has-many-through-and-has-and-belongs-to-many .

如果你想使用has_and_belongs_to_many,你的模型看起来像这样:

class Booking < ApplicationRecord
has_and_belongs_to_many :destinations
end
class Destination < ApplicationRecord
has_and_belongs_to_many :bookings
end

迁移将是这样的:

class CreateBookingsAndDestinations < ActiveRecord::Migration[6.0]
def change
create_table :bookings do |t|
# ...
end
create_table :destinations do |t|
# ...
end
create_table :bookings_destinations, id: false do |t|
t.belongs_to :booking
t.belongs_to :destination
end
end
end

警告:根据你的问题,我假设你想预订一个目的地。如果你想要一个目的地有很多预订,反之亦然,Sean的答案很好。

我认为你误解了外键/关联在数据库中的工作方式。

听起来您需要在预订表中有一个列来"引用"。目的地表中的值列(也可能相反),如:

bookings.location -> destinations.location_iddestinations.location_id -> bookings.location

这并不是我们所说的"参考"在关系数据库中。相反,当你说一个表(例如,一个'comments'表)引用另一个表(例如,一个comments表引用一个用户表)时,我们通常的意思是我们将被引用表的主键列(例如,用户id)存储在第一个表(例如comments.user_id --> users.id)的列中。

从英语语言的角度来看,我希望您希望预订指向目的地,所以我将假设我们希望预订表指向目的地表,如下所示:

booking.location -> destinations.id

在Ruby on Rails中,约定是命名一个存储与它引用的表相同的关联的列,加上_id,约定是这样的:

booking.destination_id -> destinations.id

在迁移中创建它的一种常用方法是:

add_reference :bookings, :destination

在数据库中添加引用时,您几乎总是希望按该值进行索引(以便您可以执行Bookings.where(destination_id: @destination.id)而不会杀死数据库)。我也是一个强烈的倡导者,让你的数据库为你执行引用完整性,所以(如果你的数据库支持它)我建议如下:

add_reference :destinations, :booking, index: true, foreign_key: true

这将防止某人删除与其相关联的预订的目的地。

最新更新