Ben RMX
Ben RMX
AEAsh Elixir
Created by Ben RMX on 9/27/2023 in #support
Breaking action chain in a before_action?
scratch that... i think you're right... created_at and updated_at comparisons in the after_action looks to be more clear.
7 replies
AEAsh Elixir
Created by Ben RMX on 9/27/2023 in #support
Breaking action chain in a before_action?
The above seems to work as I expected... But now that you mentioned Ash.Changeset.set_result , I'm going to try using that in a before_action ... since that around_action piece looks a bit hairy to me
7 replies
AEAsh Elixir
Created by Ben RMX on 9/27/2023 in #support
Breaking action chain in a before_action?
I've been messing around and just came up with the following:
defmodule MyApp.MyContext.Changes.EventDuplicationBarrier do
use Ash.Resource.Change

@impl true
def change(changeset, _opts, _context) do
Ash.Changeset.around_action(changeset, fn changeset, callback ->
case load_existing_event(changeset) do
{:ok, result} -> {:ok, result, changeset, %{notifications: []}}
{:error, _} -> callback.(changeset)
end
end)
end

defp load_existing_event(changeset) do
MyApp.MyContext.Event.get_by_id(changeset.attributes[:id], tenant: changeset.tenant)
end
end
defmodule MyApp.MyContext.Changes.EventDuplicationBarrier do
use Ash.Resource.Change

@impl true
def change(changeset, _opts, _context) do
Ash.Changeset.around_action(changeset, fn changeset, callback ->
case load_existing_event(changeset) do
{:ok, result} -> {:ok, result, changeset, %{notifications: []}}
{:error, _} -> callback.(changeset)
end
end)
end

defp load_existing_event(changeset) do
MyApp.MyContext.Event.get_by_id(changeset.attributes[:id], tenant: changeset.tenant)
end
end
and
actions do
defaults [:read]

create :add do
description "Adds an Event to the data store, or no-op if the event already exists. No fields are actually UPSERTed."
upsert? true
upsert_fields [:id]

# Changes for this action, and ORDER MATTERS.
change MyApp.MyContext.Changes.EventDuplicationBarrier
change MyApp.MyContext.Changes.ObanScheduleEventWorker
end

read :get_by_id do
argument :id, :uuid

filter expr(id: arg(:id))
end
actions do
defaults [:read]

create :add do
description "Adds an Event to the data store, or no-op if the event already exists. No fields are actually UPSERTed."
upsert? true
upsert_fields [:id]

# Changes for this action, and ORDER MATTERS.
change MyApp.MyContext.Changes.EventDuplicationBarrier
change MyApp.MyContext.Changes.ObanScheduleEventWorker
end

read :get_by_id do
argument :id, :uuid

filter expr(id: arg(:id))
end
7 replies
AEAsh Elixir
Created by Ben RMX on 9/26/2023 in #support
Does attribute and action order matter? and Upsert fields?
thanks!
10 replies
AEAsh Elixir
Created by Ben RMX on 9/26/2023 in #support
Does attribute and action order matter? and Upsert fields?
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"]
10 replies
AEAsh Elixir
Created by Ben RMX on 9/26/2023 in #support
Does attribute and action order matter? and Upsert fields?
great! I'll confirm bug fix after the release. thanks!
10 replies
AEAsh Elixir
Created by pragdave on 9/26/2023 in #support
Bi-directional JSON/GraphQL interfaces
A tangential idle thought is to take inspiration from a related example of Nx.Serving from either Sean Moriarty or Jose -- I can't remember who. Where they presented a set phoenix front ends, which were cluster-connected to a set of backend strongly GPU-powered BEAM nodes running Nx.Serving ... and they just used normal BEAM distributed process mechanism for the front-end->backend service integrations So, maybe it would be possible for a phoenix front-end process to use normal BEAM cluster communications to make RPC requests to Ash-Resources (modules) deployed on clustered backend nodes? The trade-off, of course, is having a BEAM cluster that spans the front-end backend services... different people, different opinions. Or... maybe even a future with "API Stub" generators... which generates an "Client SDK" that has perfect fidelity with the actual backend Ash API (of Ash Resourcess) for the front-end to include as a library... and it just does all the magic, like gRPC, to talk to its corresponding backend service? --- Is this what the ash-json-api-wrapper does? I'm not familiar with the wrapper . Doesn't matter if it's actually HTTP or something like NATS (at-most-once type messaging) under the hood. Interesting hypothetical by pragdave... 🙂
8 replies
AEAsh Elixir
Created by Ben RMX on 9/23/2023 in #support
GraphQL :type, prefix based on Context?
Ok. To recap what I think you're saying is that 1. Just having type :ticket w/o extension will result in compile time error 2. That, it is possible to write extension to both prefix the GraphQL type (in GraphQL schema) and to avoid a compile time problem with multiple type :ticket 3. That you suggest against writing an extension, and that just manually prefixing (e.g. type :helpdesk_support_ticket) is the easier/safer bet. Did I understand correctly? If so, thanks! 👍
8 replies