Skip to content

get_operations_from_snapshots/2 omits Phase.Create when an explicit fk attribute precedes the identity key #726

@jechol

Description

@jechol

Code of Conduct

  • I agree to follow this project's Code of Conduct

AI Policy

  • I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.

Versions

Elixir 1.19.5
Erlang/OTP 28.2

ash_postgres 2.8.0 : 3b3c987
ash 3.19.3 : c5c74ccf0a00502e70878dc996c5b682f14f66e1
ash_sql 0.5.0 : 8f9f620242a7f286418409597fc1201a977129ba

Operating system

macOS 26.3.1

Current Behavior

For a brand-new resource, AshPostgres.MigrationGenerator.get_operations_from_snapshots/2
can omit Phase.Create when an explicit foreign key attribute is declared before the
attribute used by an identity.

I reduced this to two otherwise equivalent resources:

  • CommentPostIdBeforeTitle
    • attribute order: [:id, :post_id, :title]
  • CommentTitleBeforePostId
    • attribute order: [:id, :title, :post_id]

Both resources have:

  • uuid_primary_key(:id)
  • an explicit post_id attribute
  • identity(:uniq_title, [:title])
  • a belongs_to(:post, Post) relationship using source_attribute(:post_id)

The [:id, :title, :post_id] case emits Phase.Create as expected.

The [:id, :post_id, :title] case does not emit Phase.Create, and instead produces
operations like AddUniqueIndex and Phase.Alter for a brand-new resource.

This does not appear to depend on adjacency. I also confirmed that it still reproduces
if a non-identity attribute like :note appears between :post_id and :title.

Reproduction

I opened a draft PR with a minimal failing test case: #725

The reproduction lives in test/migration_generator_test.exs.

The test defines:

  • Post
  • CommentPostIdBeforeTitle
  • CommentTitleBeforePostId

and compares the output of:

AshPostgres.MigrationGenerator.get_snapshots/2
AshPostgres.MigrationGenerator.get_operations_from_snapshots([], snapshots)

The failing assertion is that both resources should emit Phase.Create, but only the
resource where the identity key attribute comes before the explicit FK attribute does so.

To reproduce from the ash_postgres repo:

mix test test/migration_generator_test.exs

Expected Behavior

The relative order of an explicit foreign key attribute and the identity key attribute
should not affect whether Phase.Create is emitted for a new resource.

Both resources should emit Phase.Create, and generated migrations should include
create table(...) for the new table regardless of whether the explicit FK attribute
is declared before or after the identity key attribute.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions