ash icon indicating copy to clipboard operation
ash copied to clipboard

Ash.Resource does not translate into Ecto.Schema with correct autogenerate

Open m0rt3nlund opened this issue 2 years ago • 5 comments

Describe the bug I am not sure if this is a bug or a feature seen from the project, but for me it is a bug.

To Reproduce

  • Create an ecto schema where some fields have defaults and autogenerate, like etc the timestamps
defmodule Shared.Config.Version do
  @moduledoc false

  schema "conf_version" do
    field(:version, :integer, default: 1)

    timestamps()
  end
end
  • Create a Ash.Resource where some attribute has defaults
defmodule Shared.Ash.Config.Version do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer

  attributes do
    uuid_primary_key :id

    attribute :version, :integer do
      default 1
    end

    update_timestamp :updated_at
    create_timestamp :inserted_at
  end

  postgres do
    table "conf_version"
    repo(Shared.Repo)
  end

  actions do
    defaults [:create, :read, :update, :destroy]
  end
end

Now try to insert each of them using Ecto Repo.insert! and only the Ecto schema is inserted with default values and the timestamps are autogenerated

One can also use MyAshResource.schema(:autogenerate_fields) to see the results of my question.

Expected behavior Expects the Ash.Resource to generate a Ecto.Schema that has the autogenerate options set

Shared.Config.Version.__schema__(:autogenerate_fields) #=> [:inserted_at, :updated_at]

Shared.Ash.Config.Version.__schema__(:autogenerate_fields) #=> []
%Shared.Config.Version{} |> dbg()

%Shared.Config.Version{} #=> %Shared.Config.Version{
  __meta__: #Ecto.Schema.Metadata<:built, "conf_version">,
  id: nil,
  version: 1,
  inserted_at: nil,
  updated_at: nil
}


%Shared.Ash.Config.Version{} |> dbg()

%Shared.Ash.Config.Version{} #=> #Shared.Ash.Config.Version<
  node: #Ash.NotLoaded<:relationship>,
  __meta__: #Ecto.Schema.Metadata<:built, "conf_version">,
  id: nil,
  version: nil,
  updated_at: nil,
  inserted_at: nil,
  aggregates: %{},
  calculations: %{},
  ...
>


m0rt3nlund avatar Sep 27 '23 07:09 m0rt3nlund

The main reason this is a problem is that I would rather not define both an Ecto.Schema and a Ash.Resource. And I also want to use Ecto.Repo functions, and this does not work very elegantly if the defaults and autogenerate does not work as in a normal Ecto.Schema

Would be very valuable to be able to mix the usages between Ash.Api.create and Ecto.Repo.insert

m0rt3nlund avatar Sep 27 '23 07:09 m0rt3nlund

Agreed, you should be able to reuse the resource as an ecto schema. However, the way we do timestamps is a bit different...I'm assuming ecto needs more than just what fields are generated, i.e it needs to know that :updated_at is only changed on update and so on. This would need more investigation, but I imagine we can accomplish this here: https://github.com/ash-project/ash/blob/main/lib/ash/resource/schema.ex

zachdaniel avatar Sep 27 '23 14:09 zachdaniel

Thanks for the quick response @zachdaniel ! By the way, the project is very good! I enjoy the DSL approach and so far it has made my project alot easier to maintain :) So thank you for your effort!

I might contribute some features as well :)

m0rt3nlund avatar Sep 27 '23 16:09 m0rt3nlund

I probably won't have time to tackle this anytime soon, but PRs/further discussion is open :)

zachdaniel avatar Sep 27 '23 16:09 zachdaniel

Understandable :) Might not be that much usage since it was not brought up allready :)

i will try to make a PR :)

m0rt3nlund avatar Sep 27 '23 16:09 m0rt3nlund