Rails 由于外键类型,模型生成失败
Rails model generation fails due to foreign key type
我使用以下命令创建了一个模型:
rails g model UserCertification user:references certification:references certification_no:string
引用了我的设计用户模型user:references
。
在 db:migrate 我收到以下错误:
原因:
ActiveRecord::MismatchedForeignKey: Column user_id
on table
user_certifications
does not match column id
on users
, which has
type bigint(20)
. To resolve this issue, change the type of the
user_id
column on user_certifications
to be :bigint. (For example
t.bigint :user_id
). Original message: Mysql2::Error: Cannot add
foreign key constraint
这是我的迁移
class CreateUserCertifications < ActiveRecord::Migration[6.0]
def change
create_table :user_certifications do |t|
t.references :user, null: false, foreign_key: true
t.references :certification, null: false, foreign_key: true
t.string :certification_no
t.timestamps
end
end
end
我尝试使用 t.references :user, null: false, foreign_key: true,type: :integer
将类型设置为整数
我也把模型删了重做了,查了之前的资料,都没有成功。
也许有人有想法?
尝试设置引用中的类型以匹配其他类型table:
t.references(:user, null: false, type: :bigint)
如果这不起作用,请尝试在 user_certifications 中显式创建外键:
t.bigint :user_id, null: false
t.references(:user)
如果两个迁移都是使用 Rails 6.0 生成的,那么人们会假设没有必要指定类型,因为 :bigint
已经是 :id
列的默认类型。在我的例子中,指定类型并没有让 Rails 高兴。添加仅添加引用的第二个迁移。
class AddReferencesToUserCertifications < ActiveRecord::Migration[6.0]
def change
add_reference :user_certifications, :user, null: false, foreign_key: true
add_reference :user_certifications, :certification, null: false, foreign_key: true
end
end
添加多个引用?
扩展已接受的答案:
t.references(:user, null: false, type: :bigint)
...如果您尝试添加多个引用,您可能会发现它仍然失败 - 但控制台错误仍会将您引导至第一个错误。
例如在我的例子中,我添加了四个引用
t.references(:user, null: false, type: :bigint)
t.references(:blog, null: false, type: :integer)
t.references(:post, null: false, type: :bigint)
t.references(:comment, null: false, type: :bigint)
或
t.references :user, null: false, type: :bigint
t.references :blog, null: false, type: :integer
t.references :post, null: false, type: :bigint
t.references :comment, null: false, type: :bigint
仅更改第一个,控制台告诉我第一个(指定类型)不起作用,并给出与未指定类型相同的错误。
更改所有四个引用都成功了,这只能让我得出结论,控制台错误是由第二个引用触发的,但显示第一个引用仍然是恶意的,而不是有问题的(目前 -不变的第二个参考)。
因此,如果您有多个参考,请将它们全部更改以匹配解决方案(而不是期望控制台告诉您您编辑的 t.references 已成功而您的第二个失败。)
如果您在 Rails 6(可能还有其他版本)中看到此消息,则该错误消息可能具有误导性并且与数据类型完全无关。
例如,根据您的示例,如果 table certifications
不存在(例如,因为拼写错误),您仍然会收到错误消息,声称 user_id 应该是 bigint,即使用户参考完全没问题。
系统地注释掉您的一些参考文献和 运行 db:migrate 和 db:rollback,直到您确定实际失败的参考文献。然后仔细检查是否正确。
由于 mismatched foreign keys reporting bug 在 Rails 6,
中非常混乱,我遇到了这个问题
与MySQL基本一致,目前Rails可以针对table中的错误列报此错误。
有一个fix in the works,应该会在近期解决。
如果您遇到此问题,您需要检查 create_table
语句中的所有引用,并查看是否存在潜在的数据类型问题 - 考虑到 Rails 6 的新默认值是 bigint
,但较早的 table 可能正在使用 int
我使用以下命令创建了一个模型:
rails g model UserCertification user:references certification:references certification_no:string
引用了我的设计用户模型user:references
。
在 db:migrate 我收到以下错误: 原因:
ActiveRecord::MismatchedForeignKey: Column
user_id
on tableuser_certifications
does not match columnid
onusers
, which has typebigint(20)
. To resolve this issue, change the type of theuser_id
column onuser_certifications
to be :bigint. (For examplet.bigint :user_id
). Original message: Mysql2::Error: Cannot add foreign key constraint
这是我的迁移
class CreateUserCertifications < ActiveRecord::Migration[6.0]
def change
create_table :user_certifications do |t|
t.references :user, null: false, foreign_key: true
t.references :certification, null: false, foreign_key: true
t.string :certification_no
t.timestamps
end
end
end
我尝试使用 t.references :user, null: false, foreign_key: true,type: :integer
我也把模型删了重做了,查了之前的资料,都没有成功。 也许有人有想法?
尝试设置引用中的类型以匹配其他类型table:
t.references(:user, null: false, type: :bigint)
如果这不起作用,请尝试在 user_certifications 中显式创建外键:
t.bigint :user_id, null: false
t.references(:user)
如果两个迁移都是使用 Rails 6.0 生成的,那么人们会假设没有必要指定类型,因为 :bigint
已经是 :id
列的默认类型。在我的例子中,指定类型并没有让 Rails 高兴。添加仅添加引用的第二个迁移。
class AddReferencesToUserCertifications < ActiveRecord::Migration[6.0]
def change
add_reference :user_certifications, :user, null: false, foreign_key: true
add_reference :user_certifications, :certification, null: false, foreign_key: true
end
end
添加多个引用?
扩展已接受的答案:
t.references(:user, null: false, type: :bigint)
...如果您尝试添加多个引用,您可能会发现它仍然失败 - 但控制台错误仍会将您引导至第一个错误。
例如在我的例子中,我添加了四个引用
t.references(:user, null: false, type: :bigint)
t.references(:blog, null: false, type: :integer)
t.references(:post, null: false, type: :bigint)
t.references(:comment, null: false, type: :bigint)
或
t.references :user, null: false, type: :bigint
t.references :blog, null: false, type: :integer
t.references :post, null: false, type: :bigint
t.references :comment, null: false, type: :bigint
仅更改第一个,控制台告诉我第一个(指定类型)不起作用,并给出与未指定类型相同的错误。
更改所有四个引用都成功了,这只能让我得出结论,控制台错误是由第二个引用触发的,但显示第一个引用仍然是恶意的,而不是有问题的(目前 -不变的第二个参考)。
因此,如果您有多个参考,请将它们全部更改以匹配解决方案(而不是期望控制台告诉您您编辑的 t.references 已成功而您的第二个失败。)
如果您在 Rails 6(可能还有其他版本)中看到此消息,则该错误消息可能具有误导性并且与数据类型完全无关。
例如,根据您的示例,如果 table certifications
不存在(例如,因为拼写错误),您仍然会收到错误消息,声称 user_id 应该是 bigint,即使用户参考完全没问题。
系统地注释掉您的一些参考文献和 运行 db:migrate 和 db:rollback,直到您确定实际失败的参考文献。然后仔细检查是否正确。
由于 mismatched foreign keys reporting bug 在 Rails 6,
中非常混乱,我遇到了这个问题与MySQL基本一致,目前Rails可以针对table中的错误列报此错误。
有一个fix in the works,应该会在近期解决。
如果您遇到此问题,您需要检查 create_table
语句中的所有引用,并查看是否存在潜在的数据类型问题 - 考虑到 Rails 6 的新默认值是 bigint
,但较早的 table 可能正在使用 int