使外键也是Rails迁移中的主键

时间:2015-01-11 04:21:29

标签: sql ruby-on-rails database ruby-on-rails-4 rails-migrations

修改

我想要一个列作为主键和来自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的迁移(反之亦然)。

2 个答案:

答案 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的回答)。