我的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表已经存在,我很困惑为什么外键创建在权限表中失败。这可能是什么问题?
答案 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