46

我对 Rails 很陌生,整晚都在努力解决这个问题,但没有运气。

我创建了 3 个模型:usersbusinessesbusiness_hours。我还添加了关联 ( business_hours belongs_to businesses which belongs_to users) 和 ( user has_one business which has_many business_hours)。

在线阅读文档似乎我现在需要在我的数据库表中为这些关系创建外键。如何使用 Rails ActiveRecord 迁移来做到这一点?我使用 PostgreSQL 作为我的数据库。

4

4 回答 4

73

目前对此接受的答案并不准确,因为它没有添加数据库外键。它只是添加整数列。

Rails 4.2.x中,当前的方法是:

http://guides.rubyonrails.org/active_record_migrations.html#foreign-keys

创建迁移:

rails generate migration migration_name

对于现有列,在迁移中添加如下外键:

class MigrationName < ActiveRecord::Migration
  def change
    add_foreign_key :business_hours, :businesses
    add_foreign_key :businesses, :users
  end
end

对于Rails 4.x,或者如果您要添加新列并希望它成为外键,您可以这样做,您可能还希望将索引指定为 true,但这不是外键要求的一部分:

http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-migration

class MigrationName < ActiveRecord::Migration
  def change
    add_reference :business_hours, :business, index: true, foreign_key: true
    add_reference :businesses, :user, index: true, foreign_key: true
  end
end
于 2015-08-07T16:00:14.223 回答
35

首先,当您使用 belongs_to 方法时,不要s在词尾使用: business_hours belongs_to business which belongs_to user

现在创建一个迁移:

rails generate migration migration_name

并在迁移中添加列:

class MigrationName < ActiveRecord::Migration
  def change
    add_foreign_key :business_hours, :businesses
    add_foreign_key :businesses, :users
  end
end

运行rake db:migrate。而已。

于 2013-04-27T21:48:16.823 回答
11

Rails 5 现在可以在迁移中添加外键,请参阅http://devdocs.io/rails~5.0/activerecord/connectionadapters/schemastatements#method-i-add_foreign_key。所以

 add_foreign_key :articles, :authors

创建

 ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id")

如果你有一个非标准的数据模型,你可以这样做。

 add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"

这创造了

 ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id")
于 2017-09-02T18:38:58.380 回答
6

我没有用 PostgreSQL 尝试过,但至少 MySQL Rails 不会创建外键,我的意思是不是真正的 db 级外键。他们创建的只是一个根据约定命名的整数。这意味着开箱即用您不会获得此假外键的索引(以便更快地查找),并且也没有数据库级别的引用完整性检查。为此,您需要执行以下操作:

ALTER TABLE your_table ADD CONSTRAINT fk_whatever_you_want_to_name_it FOREIGN KEY   (foreign_key_name) REFERENCES another_table(its_primary_key)

在 Rails 迁移中,您可以将其作为字符串参数传递给“执行”函数。添加“真实”外键也会自动创建索引。至少对我来说,这是一个相当令人讨厌的惊喜。

于 2013-10-31T17:34:49.527 回答