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