Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveRecord migrations report an error on the wrong column #42661

Closed
lelandmiller opened this issue Jun 30, 2021 · 1 comment · Fixed by #42691
Closed

ActiveRecord migrations report an error on the wrong column #42661

lelandmiller opened this issue Jun 30, 2021 · 1 comment · Fixed by #42691

Comments

@lelandmiller
Copy link

lelandmiller commented Jun 30, 2021

I experienced this in MySQL, though it may show in other adapters. I did not see this in the SQLite adapter.

In this case the error reported when running this migration indicated that the problematic column was the bigint_id_model foreign key column, when it was actually the integer_id_model.

We seem to report the first column for other issues on the second column as well, this was just the first one I saw.

Please let me know if there is anything I can do to improve the self-executing test case as well. If it is preferred to handle database creation and dropping in the test I can do that as well 😄

Steps to reproduce

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "activerecord", "6.1.0"
  gem "mysql2"
end

require "active_record"
require "minitest/autorun"
require "logger"

ActiveRecord::Base.establish_connection(
  adapter: "mysql2",
  user: "root",
  database: "migration_error_issue_test"
)
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :integer_id_models, id: false do |t|
    t.integer :id, primary_key: true
  end

  create_table :bigint_id_models do |t|
  end
end


class CreateRelationshipModels < ActiveRecord::Migration[6.1]
  def change
    create_table :relationship_models do |t|
      t.references :bigint_id_model, null: false, foreign_key: true
      t.references :integer_id_model, null: false, foreign_key: true

      t.timestamps
    end
  end
end

class BugTest < Minitest::Test
  def test_migration_up
    CreateRelationshipModels.migrate(:up)

  rescue => error
    p error
    refute_includes error.message, "bigint_id_model_id"
    assert_includes error.message, "integer_id_model_id"
  end
end

Expected behavior

The error reported should mention the integer_id_model reference having the wrong type.

Actual behavior

The error reported mentions the bigint_id_model reference having the wrong type.

System configuration

Rails version: 6.1.0

Ruby version: 2.6.3

@davidstosik
Copy link
Contributor

davidstosik commented Dec 22, 2021

I have experienced the same issue in Rails 7, with such migration:

class CreatePurchases < ActiveRecord::Migration[7.0]
  def change
    create_table :purchases do |t|
      t.references :item, null: false, foreign_key: true
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end

The issue was not even about the column types (this app is recent and all id columns are bigint), it was caused by the fact that the users table does not exist (the User model is backed by a table named secure_users, for reasons).

The error was:

== 20211222000747 CreatePurchases: migrating ==================================
-- create_table(:purchases)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Column `item_id` on table `purchases` does not match column `id` on `items`, which has type `bigint(20)`. To resolve this issue, change the type of the `item_id` column on `purchases` to be :bigint. (For example `t.bigint :item_id`).
Original message: Mysql2::Error: Cannot add foreign key constraint
[...]/db/migrate/20211222000747_create_purchases.rb:3:in `change'

Caused by:
ActiveRecord::MismatchedForeignKey: Column `item_id` on table `purchases` does not match column `id` on `items`, which has type `bigint(20)`. To resolve this issue, change the type of the `item_id` column on `purchases` to be :bigint. (For example `t.bigint :item_id`).
Original message: Mysql2::Error: Cannot add foreign key constraint
[...]/db/migrate/20211222000747_create_purchases.rb:3:in `change'

Caused by:
Mysql2::Error: Cannot add foreign key constraint
[...]/db/migrate/20211222000747_create_purchases.rb:3:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

And the fix was to change foreign_key: true to foreign_key: { to_table: :secure_users } on the second line of the migration. The error message was not helpful at all for me to figure it out, this issue was (thanks @lelandmiller!).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants