Skip to content

Don't pass type: :id to scope references in generated migrations#6635

Open
eagle-head wants to merge 2 commits intophoenixframework:mainfrom
eagle-head:fix-mysql-references-column-type
Open

Don't pass type: :id to scope references in generated migrations#6635
eagle-head wants to merge 2 commits intophoenixframework:mainfrom
eagle-head:fix-mysql-references-column-type

Conversation

@eagle-head
Copy link
Contributor

Summary

Fixes #6422.

The scope reference in the migration template (migration.exs.eex, line 10) was passing type: :id explicitly to references(). In Ecto's MySQL adapter, :id maps to integer (signed 32-bit), while the default PK is bigint unsigned auto_increment. This type mismatch causes:

(MyXQL.Error) (1005) (ER_CANT_CREATE_TABLE) Can't create table (errno: 150 "Foreign key constraint is incorrectly formed")

Ecto type mapping on MySQL

references() option Ecto type MySQL SQL Matches default PK?
(no type) :bigserial (default) BIGINT UNSIGNED Yes
type: :bigserial :bigserial BIGINT UNSIGNED Yes
type: :id :id integer (32-bit) No — errno 150

Before (broken on MySQL)

add :user_id, references(:users, type: :id, on_delete: :delete_all)

After (works on all adapters)

add :user_id, references(:users, on_delete: :delete_all)

By omitting type: when it's :id, Ecto defaults to :bigserial which correctly maps to BIGINT UNSIGNED on MySQL. Non-:id types like :binary_id are still passed explicitly.

Changes

  • priv/templates/phx.gen.schema/migration.exs.eex — conditionally omit type: for scope references when schema_migration_type == :id
  • Unit tests for both :id (omitted) and :binary_id (kept) scope types
  • MySQL integration test with scoped resources verifying no errno 150

The scope reference in the migration template was passing type: :id
explicitly to references(). In Ecto's MySQL adapter, :id maps to
integer (32-bit signed), while the default PK is bigint unsigned,
causing ER_CANT_CREATE_TABLE (errno 150).

By omitting type: when it's :id, Ecto defaults to :bigserial which
correctly maps to BIGINT UNSIGNED on MySQL. Non-:id types like
:binary_id are still passed explicitly.

Fixes phoenixframework#6422
Verifies that scoped resources with foreign key references work
correctly on MySQL after the scope migration template fix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scope column type for MySQL

1 participant