Rails迁移:使用替代名称的t.references?


120

因此,对于学校课程,我有一个像这样的create_table:

create_table :courses do |t|
  t.string :name
  t.references :course
  t.timestamps
end

但我想参考 2门其他课程,如:

has_many :transferrable_as # A Course
has_many :same_as          # Another Course

我可以说以下吗?

t.references :transferrable_as, :as=> :course

Answers:


161

您可以在初始迁移/列定义(至少当前在Rails 5中)中完成所有操作:

t.references :transferable_as, index: true, foreign_key: {to_table: :courses}
t.references :same_as, index: true, foreign_key: {to_table: :courses}

10
这在Rails 5.1上有效,其他建议均无效。它更干净,而且感觉不错。
stephenmurdoch

2
我使用Rails 5.1.4,但不起作用。当我以foreign_key这种方式在表创建中指定一个选项时,会引发一个错误,提示我正在创建的表不存在...因此,我怀疑官方API确实不支持该表。
2015年

3
我也读了index已添加到外键的像Rails stackoverflow.com/questions/39769981/...
乔纳森·雷耶斯

98

您可以这样操作:

create_table :courses do |t|
  t.string :name
  t.references :transferrable_as
  t.references :same_as
  t.timestamps
end

t.belongs_to用作别名t.references

您不能foreign_key: true在这两个参考行中添加。如果要在数据库级别将它们标记为外键,则需要进行以下迁移:

add_foreign_key :courses, :courses, column: :transferrable_as_id
add_foreign_key :courses, :courses, column: :same_as_id

更新资料

在Rails 5.1及更高版本中,您可以create_table像这样在块中的迁移中添加外键:

create_table :courses do |t|
  t.string :name
  t.references :transferrable_as, foreign_key: { to_table: 'courses' }
  t.references :same_as, foreign_key: { to_table: 'courses' }
  t.timestamps
end

5
关于无法添加foreign_key: true到参考行的部分使我感到震惊。添加add_foreign_key并为这些列指定列名就可以了。
马修·克拉克

这在Rails中可以立即使用吗?根据stackoverflow.com/a/22384289/239657,这需要schema_plus宝石。Rails的add_reference文档未提及:references选项。
贝尼·切尔尼亚夫斯基-帕斯金

1
我没有遵循该references:选项的用途(相反,那t.references不是仅与模型级别相关,而是由external_key考虑的add_foreign_key?来处理?
MCB

1
@MCB t.references说:“向该表添加一个字段,该字段是另一个表的主键。” 该references:选项告诉它它是哪个表的主键(如果字段名称不清楚,则需要此表)。该add_foreign_key函数在此告诉数据库强制的参照完整性。
Toby 1 Kenobi

2
一直以来,@ MCB我都知道你一直都是对的。上面的第一个评论是完全正确的-这些add_foreign_key行负责通知数据库什么是什么的外键。该references:参数不执行任何操作。
Toby 1 Kenobi

13

我认为该线程具有另一种更类似于Rails的方式: 脚手架ActiveRecord:相同数据类型的两列

在迁移中:

t.belongs_to:transferrable_as

t.belongs_to:same_as


1
但是数据库如何知道将表链接到哪个外键?我正在使用Postgres数据库尝试此操作,这给我一个错误PG::UndefinedTable: ERROR,正在尝试向不存在的表添加外键约束。
Toby 1 Kenobi

如果有人想知道, belongs_to只是一个别名,以references等具有完全相同的功能。
杰森·斯威特

11

作为对该问题的补充回答-模型应具有以下行以完成关联:

    belongs_to :transferrable_as, class_name: "Course"
    belongs_to :same_as, class_name: "Course"

3

我不references接受该:as选项,但是您可以手动创建列...

create_table :courses do |t| 
  t.string  :name 
  t.integer :course1_id
  t.integer :course2_id 
  t.timestamps 
end 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.