ash-project / ash

A declarative, extensible framework for building Elixir applications.
https://www.ash-hq.org
MIT License
1.63k stars 216 forks source link

Union type is not correctly inferred from `_union_type` #1448

Closed yujonglee closed 2 months ago

yujonglee commented 2 months ago

Describe the bug Union type is not correctly inferred from _union_typewhen submitting form. This only happens if there's two embedded resource with same fields.

For example, when this form is submitted,

%{
  "config" => %{
    "_form_type" => "create",
    "_persistent_id" => "0",
    "_touched" => "_form_type,_persistent_id,_touched,_union_type,owner,repo",
    "_union_type" => "github_discussion",
    "owner" => "fastrepl",
    "repo" => "canary"
  },
}

Created record's config field is %Ash.Union{type: :github_issue}, not %Ash.Union{type: :github_discussion}.

To Reproduce

defmodule Canary.Sources.GithubDiscussion.Config do
  use Ash.Resource, data_layer: :embedded

  attributes do
    attribute :owner, :string, allow_nil?: false
    attribute :repo, :string, allow_nil?: false
  end

  actions do
    defaults [:read, create: [:owner, :repo], update: [:owner, :repo]]
  end
end
defmodule Canary.Sources.GithubIssue.Config do
  use Ash.Resource, data_layer: :embedded

  attributes do
    attribute :owner, :string, allow_nil?: false
    attribute :repo, :string, allow_nil?: false
  end

  actions do
    defaults [:read, create: [:owner, :repo], update: [:owner, :repo]]
  end
end
defmodule Canary.Sources.Source do
  use Ash.Resource,
    domain: Canary.Sources,
    data_layer: AshPostgres.DataLayer

  attributes do
    uuid_primary_key :id
    attribute :config, Canary.Type.SourceConfig, allow_nil?: false
  end
# ...

If I change repo field in GithubDiscussion.Config to repo2, %Ash.Union{type: :github_discussion} is created. So it only fails to find the correct resource when there's multiple resources with same fields.

I expected resource to be chosen based on _union_type.

Runtime

zachdaniel commented 2 months ago

@yujonglee could you provide a test that reproduces this?

zachdaniel commented 2 months ago

Or a reproduction project?

yujonglee commented 2 months ago

@zachdaniel

Sure. Here's minimal repro project repo:

https://github.com/yujonglee/ash-union-repro/blob/05e9779051b30d587bbefd859a802e88153b4e38/test/repro_test.exs#L64

mix test should surface problem with failing test.

zachdaniel commented 2 months ago

Fixed in ash main. We've fixed this by honoring _union_type in ash core.