运行rails迁移时无法添加外键约束错误

时间:2017-02-23 17:54:37

标签: mysql ruby-on-rails ruby-on-rails-4 activerecord

我的MySQL数据库中有一个用户表。在我的rails 4应用程序中,我创建了一个Permission模型,如下所示:

rails g model Permission user:references privilege:references

当我运行迁移以创建权限表时,表确实在数据库中创建,但是我收到以下错误:

== 20170223171936 CreatePermissions: migrating ================================
-- create_table(:permissions)
rake aborted!
StandardError: An error has occurred:

Mysql2::Error: Cannot add foreign key constraint: ALTER TABLE `permissions` ADD CONSTRAINT `fk_rails_d9cfa3c257`
FOREIGN KEY (`user_id`)
  REFERENCES `users` (`id`)

由于users表已经存在,我很困惑为什么外键创建在权限表中失败。这可能是什么问题?

6 个答案:

答案 0 :(得分:13)

我修好了。生成的权限表中的users_id列类型为int(11),users表中id列的列类型为int(11)unsigned。 TLDR:外键列的数据类型和引用列的数据类型应该相同。

您可以通过运行show full columns from <table_name>来查看列类型。您还可以通过运行show engine innodb status来查看添加外键失败的确切原因。

我创建了一个迁移,以从users id中删除unsigned属性,现在列类型已对齐,外键添加工作正常!

答案 1 :(得分:1)

对我来说,问题是Rails在为我要创建的关系查找错误的表。我正在创建一个自我参照表,并在迁移过程中运行它:

add_reference :categories, :linked_category, foreign_key: true

我希望将列名设置为linked_category_id。

发生的事情是Rails在寻找一个不存在的linked_categories表:

FOREIGN KEY (`linked_category_id`)
  REFERENCES `linked_categories` (`id`)

解决方案是设置外键应引用哪个表:

add_reference :categories, :linked_category, foreign_key: { to_table: :categories }

答案 2 :(得分:0)

我经常遇到这个问题,因为外键所针对的列上缺少索引。

答案 3 :(得分:0)

使用此

rails g model Permission user:integer:index privilege:integer:index

答案 4 :(得分:0)

自从升级到Rails 5.2以来,我一直在处理此问题:

我继续创建迁移 rails g model Example user:references

然后,在运行迁移之前,我先打开迁移文件,然后将t.references :user, foreign_key: true编辑为t.references :user, foreign_key: true, type: :integer

然后运行rake db:migrate应该成功运行并为您添加外键。

答案 5 :(得分:-2)

将foreign_key设置为false - &gt; t.references:user,foreign_key:false

重置数据库 - &gt; rails db:migrate:reset,

将foreign_key设置为true - &gt; t.references:user,foreign_key:true

然后迁移数据库 - &gt; rails db:migrate