diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 6395257..4820ac8 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -18,7 +18,7 @@ jobs: matrix: otp: ["23"] elixir: ["1.11.0"] - ash: ["master", "1.50.20"] + ash: ["master", "1.51.0"] pg_version: ["9.6", "11"] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 1353090..86459f8 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -229,14 +229,14 @@ defmodule AshPostgres.MigrationGenerator do end defp add_order_to_operation(%{attribute: attribute} = op, attributes) do - order = Enum.find_index(attributes, &(&1.name == attribute.name)) + order = Enum.find_index(attributes, &(&1.source == attribute.source)) attribute = Map.put(attribute, :order, order) %{op | attribute: attribute} end defp add_order_to_operation(%{new_attribute: attribute} = op, attributes) do - order = Enum.find_index(attributes, &(&1.name == attribute.name)) + order = Enum.find_index(attributes, &(&1.source == attribute.source)) attribute = Map.put(attribute, :order, order) %{op | new_attribute: attribute} @@ -330,7 +330,7 @@ defmodule AshPostgres.MigrationGenerator do new_snapshot | attributes: Enum.map(new_snapshot.attributes, fn attribute -> - if attribute.name in primary_key do + if attribute.source in primary_key do %{attribute | primary_key?: true} else %{attribute | primary_key?: false} @@ -346,8 +346,8 @@ defmodule AshPostgres.MigrationGenerator do attributes |> Enum.with_index() |> Enum.map(fn {attr, i} -> Map.put(attr, :order, i) end) - |> Enum.group_by(& &1.name) - |> Enum.map(fn {name, attributes} -> + |> Enum.group_by(& &1.source) + |> Enum.map(fn {source, attributes} -> size = attributes |> Enum.map(& &1.size) @@ -361,13 +361,13 @@ defmodule AshPostgres.MigrationGenerator do end %{ - name: name, - type: merge_types(Enum.map(attributes, & &1.type), name, table), + source: source, + type: merge_types(Enum.map(attributes, & &1.type), source, table), size: size, default: merge_defaults(Enum.map(attributes, & &1.default)), allow_nil?: Enum.any?(attributes, & &1.allow_nil?) || Enum.count(attributes) < count, generated?: Enum.any?(attributes, & &1.generated?), - references: merge_references(Enum.map(attributes, & &1.references), name, table), + references: merge_references(Enum.map(attributes, & &1.references), source, table), primary_key?: false, order: attributes |> Enum.map(& &1.order) |> Enum.min() } @@ -534,7 +534,7 @@ defmodule AshPostgres.MigrationGenerator do defp pkey_names(attributes) do attributes |> Enum.filter(& &1.primary_key?) - |> Enum.map(& &1.name) + |> Enum.map(& &1.source) |> Enum.sort() end @@ -1263,12 +1263,12 @@ defmodule AshPostgres.MigrationGenerator do defp attribute_operations(snapshot, old_snapshot, opts) do attributes_to_add = Enum.reject(snapshot.attributes, fn attribute -> - Enum.find(old_snapshot.attributes, &(&1.name == attribute.name)) + Enum.find(old_snapshot.attributes, &(&1.source == attribute.source)) end) attributes_to_remove = Enum.reject(old_snapshot.attributes, fn attribute -> - Enum.find(snapshot.attributes, &(&1.name == attribute.name)) + Enum.find(snapshot.attributes, &(&1.source == attribute.source)) end) {attributes_to_add, attributes_to_remove, attributes_to_rename} = @@ -1278,7 +1278,7 @@ defmodule AshPostgres.MigrationGenerator do snapshot.attributes |> Enum.map(fn attribute -> {attribute, - Enum.find(old_snapshot.attributes, &(&1.name == attribute.name && &1 != attribute))} + Enum.find(old_snapshot.attributes, &(&1.source == attribute.source && &1 != attribute))} end) |> Enum.filter(&elem(&1, 1)) @@ -1439,7 +1439,7 @@ defmodule AshPostgres.MigrationGenerator do defp resolve_renames(_table, [], removing, _opts), do: {[], removing, []} defp resolve_renames(table, [adding], [removing], opts) do - if renaming_to?(table, removing.name, adding.name, opts) do + if renaming_to?(table, removing.source, adding.source, opts) do {[], [], [{adding, removing}]} else {[adding], [removing], []} @@ -1476,9 +1476,9 @@ defmodule AshPostgres.MigrationGenerator do defp renaming?(table, removing, opts) do if opts.no_shell? do - raise "Unimplemented: cannot determine: Are you renaming #{table}.#{removing.name}? without shell input" + raise "Unimplemented: cannot determine: Are you renaming #{table}.#{removing.source}? without shell input" else - Mix.shell().yes?("Are you renaming #{table}.#{removing.name}?") + Mix.shell().yes?("Are you renaming #{table}.#{removing.source}?") end end @@ -1491,7 +1491,7 @@ defmodule AshPostgres.MigrationGenerator do defp get_new_attribute(adding, tries) do name = Mix.shell().prompt( - "What are you renaming it to?: #{Enum.map_join(adding, ", ", & &1.name)}" + "What are you renaming it to?: #{Enum.map_join(adding, ", ", & &1.source)}" ) name = @@ -1501,7 +1501,7 @@ defmodule AshPostgres.MigrationGenerator do nil end - case Enum.find(adding, &(to_string(&1.name) == name)) do + case Enum.find(adding, &(to_string(&1.source) == name)) do nil -> get_new_attribute(adding, tries - 1) new_attribute -> new_attribute end @@ -1546,7 +1546,12 @@ defmodule AshPostgres.MigrationGenerator do end) |> Map.update!(:attributes, fn attributes -> Enum.map(attributes, fn attribute -> - if attribute.name == relationship.destination_field do + destination_field_source = + relationship.destination + |> Ash.Resource.Info.attribute(relationship.destination_field) + |> Map.get(:source) + + if attribute.source == destination_field_source do source_attribute = Ash.Resource.Info.attribute(relationship.source, relationship.source_field) @@ -1657,7 +1662,9 @@ defmodule AshPostgres.MigrationGenerator do resource |> Ash.Resource.Info.attributes() - |> Enum.map(&Map.take(&1, [:name, :type, :default, :allow_nil?, :generated?, :primary_key?])) + |> Enum.map( + &Map.take(&1, [:name, :source, :type, :default, :allow_nil?, :generated?, :primary_key?]) + ) |> Enum.map(fn attribute -> default = default(attribute, repo) @@ -1687,6 +1694,7 @@ defmodule AshPostgres.MigrationGenerator do |> Map.put(:default, default) |> Map.put(:size, size) |> Map.put(:type, type) + |> Map.delete(:name) end) |> Enum.map(fn attribute -> references = find_reference(resource, table, attribute) @@ -1697,9 +1705,15 @@ defmodule AshPostgres.MigrationGenerator do defp find_reference(resource, table, attribute) do Enum.find_value(Ash.Resource.Info.relationships(resource), fn relationship -> - if attribute.name == relationship.source_field && relationship.type == :belongs_to && + source_field_name = + relationship.source + |> Ash.Resource.Info.attribute(relationship.source_field) + |> Map.get(:source) + + if attribute.source == source_field_name && relationship.type == :belongs_to && foreign_key?(relationship) do - configured_reference = configured_reference(resource, table, attribute.name, relationship) + configured_reference = + configured_reference(resource, table, attribute.source, relationship) %{ destination_field: relationship.destination_field, @@ -1917,8 +1931,14 @@ defmodule AshPostgres.MigrationGenerator do {other, nil} end + attribute = + if Map.has_key?(attribute, :name) do + Map.put(attribute, :source, String.to_atom(attribute.name)) + else + Map.update!(attribute, :source, &String.to_atom/1) + end + attribute - |> Map.update!(:name, &String.to_atom/1) |> Map.put(:type, type) |> Map.put(:size, size) |> Map.put_new(:default, "nil") @@ -1936,7 +1956,10 @@ defmodule AshPostgres.MigrationGenerator do |> Map.put_new(:on_update, nil) |> Map.update!(:on_delete, &(&1 && String.to_atom(&1))) |> Map.update!(:on_update, &(&1 && String.to_atom(&1))) - |> Map.put(:name, Map.get(references, :name) || "#{table}_#{attribute.name}_fkey") + |> Map.put( + :name, + Map.get(references, :name) || "#{table}_#{attribute.source}_fkey" + ) |> Map.put_new(:multitenancy, %{ attribute: nil, strategy: nil, diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 0321ba0..4459f48 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -92,7 +92,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", "references(:#{table}", [ "column: #{inspect(destination_field)}", @@ -129,7 +129,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", "references(:#{table}", [ "column: #{inspect(destination_field)}", @@ -163,7 +163,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", inspect(attribute.type), maybe_add_default(attribute.default), maybe_add_primary_key(attribute.primary_key?), @@ -191,7 +191,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", "references(:#{table}", [ "column: #{inspect(destination_field)}", @@ -227,7 +227,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", "references(:#{table}", [ "column: #{inspect(destination_field)}", @@ -257,7 +257,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", "references(:#{table}", [ "column: #{inspect(destination_field)}", @@ -277,7 +277,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do def up(%{attribute: %{type: :bigint, default: "nil", generated?: true} = attribute}) do [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", ":bigserial", maybe_add_null(attribute.allow_nil?), maybe_add_primary_key(attribute.primary_key?) @@ -287,7 +287,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do def up(%{attribute: %{type: :integer, default: "nil", generated?: true} = attribute}) do [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", ":serial", maybe_add_null(attribute.allow_nil?), maybe_add_primary_key(attribute.primary_key?) @@ -302,7 +302,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do end [ - "add #{inspect(attribute.name)}", + "add #{inspect(attribute.source)}", "#{inspect(attribute.type)}", maybe_add_null(attribute.allow_nil?), maybe_add_default(attribute.default), @@ -370,7 +370,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do inspect(attribute.type) end - "modify #{inspect(attribute.name)}, #{type_or_reference}#{alter_opts(attribute, old_attribute)}" + "modify #{inspect(attribute.source)}, #{type_or_reference}#{alter_opts(attribute, old_attribute)}" end defp reference( @@ -533,11 +533,11 @@ defmodule AshPostgres.MigrationGenerator.Operation do ] def up(%{old_attribute: old_attribute, new_attribute: new_attribute, table: table}) do - "rename table(:#{table}), #{inspect(old_attribute.name)}, to: #{inspect(new_attribute.name)}" + "rename table(:#{table}), #{inspect(old_attribute.source)}, to: #{inspect(new_attribute.source)}" end def down(%{new_attribute: old_attribute, old_attribute: new_attribute, table: table}) do - "rename table(:#{table}), #{inspect(old_attribute.name)}, to: #{inspect(new_attribute.name)}" + "rename table(:#{table}), #{inspect(old_attribute.source)}, to: #{inspect(new_attribute.source)}" end end @@ -549,19 +549,19 @@ defmodule AshPostgres.MigrationGenerator.Operation do """ # Attribute removal has been commented out to avoid data loss. See the migration generator documentation for more # If you uncomment this, be sure to also uncomment the corresponding attribute *addition* in the `down` migration - # remove #{inspect(attribute.name)} + # remove #{inspect(attribute.source)} """ end def up(%{attribute: attribute}) do - "remove #{inspect(attribute.name)}" + "remove #{inspect(attribute.source)}" end def down(%{attribute: attribute, multitenancy: multitenancy, commented?: true}) do prefix = """ # This is the `down` migration of the statement: # - # remove #{inspect(attribute.name)} + # remove #{inspect(attribute.source)} # """ diff --git a/lib/types/types.ex b/lib/types/types.ex index 131f8e8..b43470d 100644 --- a/lib/types/types.ex +++ b/lib/types/types.ex @@ -13,7 +13,11 @@ defmodule AshPostgres.Types do def parameterized_type(type, constraints) do if Ash.Type.ash_type?(type) do - parameterized_type(Ash.Type.ecto_type(type), constraints) + if Ash.Type.cast_in_query?(type) do + parameterized_type(Ash.Type.ecto_type(type), constraints) + else + :any + end else if is_atom(type) && :erlang.function_exported(type, :type, 1) do {:parameterized, type, constraints || []} diff --git a/mix.exs b/mix.exs index a67f05c..d73d8c2 100644 --- a/mix.exs +++ b/mix.exs @@ -97,7 +97,7 @@ defmodule AshPostgres.MixProject do {:ecto, github: "elixir-ecto/ecto", branch: "master", override: true}, {:jason, "~> 1.0"}, {:postgrex, ">= 0.0.0"}, - {:ash, ash_version("~> 1.50 and >= 1.50.20")}, + {:ash, ash_version("~> 1.51 and >= 1.51.0")}, {:git_ops, "~> 2.4.5", only: :dev}, {:ex_doc, "~> 0.22", only: :dev, runtime: false}, {:ex_check, "~> 0.11.0", only: :dev}, diff --git a/test/filter_test.exs b/test/filter_test.exs index fab7900..225b1da 100644 --- a/test/filter_test.exs +++ b/test/filter_test.exs @@ -419,6 +419,17 @@ defmodule AshPostgres.FilterTest do |> Ash.Query.filter(status_enum == ^"open") |> Api.read_one!() end + + test "it allows simple filtering without casting" do + Post + |> Ash.Changeset.new(status_enum_no_cast: "open") + |> Api.create!() + + assert %{status_enum_no_cast: :open} = + Post + |> Ash.Query.filter(status_enum_no_cast == ^"open") + |> Api.read_one!() + end end describe "atom filters" do diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index e815eb7..bba897f 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -53,6 +53,7 @@ defmodule AshPostgres.Test.Post do attribute(:decimal, :decimal, default: Decimal.new(0)) attribute(:status, AshPostgres.Test.Types.Status) attribute(:status_enum, AshPostgres.Test.Types.StatusEnum) + attribute(:status_enum_no_cast, AshPostgres.Test.Types.StatusEnumNoCast, source: :status_enum) create_timestamp(:created_at) end diff --git a/test/support/types/status_enum_no_cast.ex b/test/support/types/status_enum_no_cast.ex new file mode 100644 index 0000000..267c248 --- /dev/null +++ b/test/support/types/status_enum_no_cast.ex @@ -0,0 +1,8 @@ +defmodule AshPostgres.Test.Types.StatusEnumNoCast do + @moduledoc false + use Ash.Type.Enum, values: [:open, :closed] + + def storage_type, do: :status + + def cast_in_query?, do: false +end