AE
Ash Elixir•2y ago
Ben RMX

Does attribute and action order matter? and Upsert fields?

Given Declaration
defmodule MyApp.MyContext.Event do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "event"
repo MyApp.MyContext.Repo
end

multitenancy do
strategy :attribute
attribute :organization_id
end

attributes do
# Tenancy, Identity and Immutability
# * Primary Key - [:organization_id, :id]
# * need to manually declare id so we do not autogenerate UUID
attribute :organization_id, :uuid, allow_nil?: false, primary_key?: true
attribute :id, :uuid, allow_nil?: false, primary_key?: true

attribute :data, :map
attribute :dataschema, :string

attribute :partitionkey, :string
attribute :sequence, :integer
attribute :source, :string, allow_nil?: false
attribute :subject, :string
attribute :time, :utc_datetime_usec
attribute :type, :string, allow_nil?: false

create_timestamp :created_at
end

identities do
identity :id, [:id]
end

actions do
defaults [:read]
create :add do
upsert? true
upsert_identity :id
upsert_fields([:id])
end
end
end
defmodule MyApp.MyContext.Event do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "event"
repo MyApp.MyContext.Repo
end

multitenancy do
strategy :attribute
attribute :organization_id
end

attributes do
# Tenancy, Identity and Immutability
# * Primary Key - [:organization_id, :id]
# * need to manually declare id so we do not autogenerate UUID
attribute :organization_id, :uuid, allow_nil?: false, primary_key?: true
attribute :id, :uuid, allow_nil?: false, primary_key?: true

attribute :data, :map
attribute :dataschema, :string

attribute :partitionkey, :string
attribute :sequence, :integer
attribute :source, :string, allow_nil?: false
attribute :subject, :string
attribute :time, :utc_datetime_usec
attribute :type, :string, allow_nil?: false

create_timestamp :created_at
end

identities do
identity :id, [:id]
end

actions do
defaults [:read]
create :add do
upsert? true
upsert_identity :id
upsert_fields([:id])
end
end
end
The above gives me the warning:
warning: the Inspect protocol has already been consolidated, an implementation for Btwb.Koohbew.Event has no effect. If you want to implement protocols after compilation or during tests, check the "Consolidation" section in the Protocol module documentation
But if I move identities and actions to above the attributes, then no warning... Given:
MyApp.MyContext.Event |>
Ash.Changeset.for_create(
:add,
%{
organization_id: "1c8345b3-f484-47a7-ad21-da17fa511966",
id: "a325ac4a-5c7b-11ee-8c99-0242ac120002",
type: "namtest2",
source: "MyEventSource.34293942394234"
})
|> Ash.Changeset.set_tenant("1c8345b3-f484-47a7-ad21-da17fa511966")
|> MyApp.MyContext.create()
MyApp.MyContext.Event |>
Ash.Changeset.for_create(
:add,
%{
organization_id: "1c8345b3-f484-47a7-ad21-da17fa511966",
id: "a325ac4a-5c7b-11ee-8c99-0242ac120002",
type: "namtest2",
source: "MyEventSource.34293942394234"
})
|> Ash.Changeset.set_tenant("1c8345b3-f484-47a7-ad21-da17fa511966")
|> MyApp.MyContext.create()
The above gives a SQL query with DO UPDATE SET on all fields Am I doing something wrong? Do actions have to be above attributes?
4 Replies
ZachDaniel
ZachDaniel•2y ago
🤔 the order of DSL sections should never matter That protocol consolidation warning can generally be ignored but, for the actual issue, you are not doing anything wrong that is a bug that I fixed yesterday in main I'm pushing a release now
Ben RMX
Ben RMXOP•2y ago
great! I'll confirm bug fix after the release. thanks!
ZachDaniel
ZachDaniel•2y ago
1.3.52 of ash_postgres is out w/ the fix
Ben RMX
Ben RMXOP•2y ago
Works! 1. Unlisted fields no longer show up in the SQL's "update set" 2. upsert_identity required at least 1 element in the list, so only used the id (identity) to effectively no-op the operation.
INSERT INTO "event" AS e0 ("id","type","source","organization_id","created_at") VALUES ($1,$2,$3,$4,$5) ON CONFLICT ("organization_id","id") DO UPDATE SET "id" = $6 RETURNING "created_at","type","time","subject","source","sequence","partitionkey","dataschema","data","id","organization_id" ["a325ac4a-5c7b-11ee-8c99-0242ac120002", "MyNewType", "MyNewSource", "1c8345b3-f484-47a7-ad21-da17fa511966", ~U[2023-09-26 15:49:17.912925Z], "a325ac4a-5c7b-11ee-8c99-0242ac120002"]
INSERT INTO "event" AS e0 ("id","type","source","organization_id","created_at") VALUES ($1,$2,$3,$4,$5) ON CONFLICT ("organization_id","id") DO UPDATE SET "id" = $6 RETURNING "created_at","type","time","subject","source","sequence","partitionkey","dataschema","data","id","organization_id" ["a325ac4a-5c7b-11ee-8c99-0242ac120002", "MyNewType", "MyNewSource", "1c8345b3-f484-47a7-ad21-da17fa511966", ~U[2023-09-26 15:49:17.912925Z], "a325ac4a-5c7b-11ee-8c99-0242ac120002"]
thanks!

Did you find this page helpful?