修改
我想要一个列作为主键和来自Rails'的外键。观点看法。也就是说使用references
方法的外键。我想做类似的事情:
def change
create_table :VipPerson, id: false do |t|
t.primary_key :person_id
t.references :person, :id, column: :person_id
t.timestamps
end
end
我希望有一个自定义主键,Rails模型也使用它来指向Person模型(见下文)。这实际上与sql-database使用的外键没有任何关系(Rails没有支持创建真正的外键,直到Rails 4.2,如Demi Magus所指出的那样。)
-
我希望在我的Rails项目中实现多表间接(MTI),因此可以像在关系数据库中一样实现继承:
table: Person
-------------
(PK) ID
Name
...
table: VipPerson (specalization of Person)
----------------
(PK) (FK) Person_ID
VIP-Status
...
因此,我需要编写一个迁移,它同时声明一个属性(此处为Person_ID
)作为(自定义)主键和外键。我不知道如何使用Rails'的方法来做到这一点。迁移DSP。
我不想使用Rails'多态关联,因为我想保证数据库中的数据完整性。我知道我也需要自定义Rails模型,但是不要谈到那个话题。主要问题是如何编写使PK也成为FK的迁移(反之亦然)。
答案 0 :(得分:2)
外键关系仅适用于最新版本的rails,如release notes中所示,这是4.2,您可以像这样使用
创建一个简单的外键
add_foreign_key :articles, :authors
生成:
ALTER TABLE "articles" ADD CONSTRAINT articles_author_id_fk FOREIGN KEY ("author_id") REFERENCES "authors" ("id")
你也应该知道add_foreign_key只会生成一个外键约束,而不是像activerecord add_column那样的列
add_column :articles, :author_id, :integer
将生成:
ALTER TABLE "articles" ADD COLUMN author_id INT(11);
您可以找到更多信息here
此外,如果你不仅仅是寻找铁轨的边缘,那么你可以找到有用的这个宝石,让你可以做你正在寻找的composite_primary_keys,你唯一拥有的东西要小心的是,你必须使用与你的rails版本兼容的版本。
我希望它有所帮助:D
答案 1 :(得分:2)
解决方案是在模型中手动设置主键和外键而不是摆弄迁移(注意,您必须通过传递" id:false"来告诉Rails不要创建默认列ID选项):
迁移:
def change
create_table :VipPerson, id: false do |t|
t.primary_key :person_id # Normal integer PK, shouldn't auto-increment
t.integer :vip_status
..... etc.
end
end
在模型中:
class VipPerson < ActiveRecord::Base
self.primary_key = "person_id"
belongs_to :person, foreign_key: "person_id"
end
只需手动指向模型中的同一列即可。在数据库层,您可以使用真正的外键约束来额外增强主键(请参阅Demi Magus的回答)。