Robert Graff
Robert Graff
AEAsh Elixir
Created by aidalgol on 5/4/2025 in #support
Rendering AshPaperTrails
@allenwyma I don't know of any good public examples, but if you find one let me know.
11 replies
AEAsh Elixir
Created by Robert Graff on 7/20/2023 in #support
How do relationships with composite keys work?
That's correct
10 replies
AEAsh Elixir
Created by Robert Graff on 8/18/2023 in #support
Duplicate input types for GraphQL
I am working on ash_graphql main. I can not figure out how to reproduce this in the test lib, but I have it working in app now using graphql_type() 🤷‍♂️
11 replies
AEAsh Elixir
Created by Robert Graff on 8/18/2023 in #support
Duplicate input types for GraphQL
I did not define a graphql_type and so it was assuming one for me. Setting my own graphql_type fixes it.
def graphql_type(_), do: :option
def graphql_type(_), do: :option
So to recap: when I use a nested union as a singular argument and array attribute in two mutations while not defining a graphql_type, absinthe throws an after compile error:
## Locations
/workspace/app/deps/ash_graphql/lib/resource/resource.ex:1385
/workspace/app/deps/ash_graphql/lib/resource/resource.ex:1385

Absinthe type identifier :feature_variant is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system


(absinthe 1.7.5) lib/absinthe/schema.ex:392: Absinthe.Schema.__after_compile__/2
(stdlib 4.3) lists.erl:1350: :lists.foldl/3
## Locations
/workspace/app/deps/ash_graphql/lib/resource/resource.ex:1385
/workspace/app/deps/ash_graphql/lib/resource/resource.ex:1385

Absinthe type identifier :feature_variant is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

Reference: https://github.com/facebook/graphql/blob/master/spec/Section%203%20--%20Type%20System.md#type-system


(absinthe 1.7.5) lib/absinthe/schema.ex:392: Absinthe.Schema.__after_compile__/2
(stdlib 4.3) lists.erl:1350: :lists.foldl/3
In my repo, I can replicate it reliably. And I'm unable to replicate it in the ash_graphql test suite.
11 replies
AEAsh Elixir
Created by Robert Graff on 8/18/2023 in #support
Duplicate input types for GraphQL
Spent some time unsuccessfully trying to write a test for ash_graphql, and while doing so figured out a work around.
11 replies
AEAsh Elixir
Created by Robert Graff on 8/18/2023 in #support
Duplicate input types for GraphQL
will do.
11 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
The union raises the struct error, but adding the form for one of the variants leads to other errors
22 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
I'm trying to get it working with just one type to start.
create_feature_form =
AshPhoenix.Form.for_create(Package, :create,
api: MyApi,
forms: [
variants: [
type: :list,
resource: PackageOption.Boolean, # or is it PackageOption Union?
create_action: :create
]
]
)
|> to_form()
create_feature_form =
AshPhoenix.Form.for_create(Package, :create,
api: MyApi,
forms: [
variants: [
type: :list,
resource: PackageOption.Boolean, # or is it PackageOption Union?
create_action: :create
]
]
)
|> to_form()
[error] GenServer #PID<0.1349.0> terminating
** (UndefinedFunctionError) function Kickplan.Environments.FeatureVariant.__struct__/0 is undefined or private
(kickplan 0.1.0) Kickplan.Environments.FeatureVariant.__struct__()
[error] GenServer #PID<0.1349.0> terminating
** (UndefinedFunctionError) function Kickplan.Environments.FeatureVariant.__struct__/0 is undefined or private
(kickplan 0.1.0) Kickplan.Environments.FeatureVariant.__struct__()
22 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
I can switch the behaviour for the union type pretty easily, but I'm not sure I'm adding forms correctly.
22 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
Got it. That makes sense now. For other reasons, I've not been able to get forms working and I haven't tested the apis
22 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
Are the validations supposed to be skipped if there's no casting?
22 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
Wow, ok. Using a map instead of a struct, the constraints and the validations are applied.
22 replies
AEAsh Elixir
Created by Robert Graff on 8/11/2023 in #support
Applying constraints to embedded union types
Package.update(
package,
%{
options: [
%Ash.Union{
type: :boolean,
value: %PackageOption.Boolean{
type: :boolean,
value: false,
key: "not a valid key",
enabled: true
}
}
]
}
)

{:ok, %MyApi.Package{
...
options: [
%Ash.Union{
value: #PackageOption.Boolean<__lateral_join_source__: nil, __meta__: #Ecto.Schema.Metadata<:built, "">, id: "e8668815-061c-4f86-bfa7-4d166fd1dba2", key: "true!", value: true, type: :boolean, enabled: true, aggregates: %{}, calculations: %{}, __order__: nil, ...>,
type: :boolean
}
]
}}
Package.update(
package,
%{
options: [
%Ash.Union{
type: :boolean,
value: %PackageOption.Boolean{
type: :boolean,
value: false,
key: "not a valid key",
enabled: true
}
}
]
}
)

{:ok, %MyApi.Package{
...
options: [
%Ash.Union{
value: #PackageOption.Boolean<__lateral_join_source__: nil, __meta__: #Ecto.Schema.Metadata<:built, "">, id: "e8668815-061c-4f86-bfa7-4d166fd1dba2", key: "true!", value: true, type: :boolean, enabled: true, aggregates: %{}, calculations: %{}, __order__: nil, ...>,
type: :boolean
}
]
}}
22 replies
AEAsh Elixir
Created by gordoneliel on 8/4/2023 in #support
Testing: How to approach testing
and
assert {:error, %Ash.Error.Forbidden{}} =
User.update_password(
user,
%{
password: new_password,
password_confirmation: new_password,
current_password: current_password
},
actor: unauthorized_user
)
assert {:error, %Ash.Error.Forbidden{}} =
User.update_password(
user,
%{
password: new_password,
password_confirmation: new_password,
current_password: current_password
},
actor: unauthorized_user
)
Seeing better patterns would be useful
10 replies
AEAsh Elixir
Created by gordoneliel on 8/4/2023 in #support
Testing: How to approach testing
This interests me. Right now we're doing:
assert {:error, %Ash.Error.Invalid{}} =
User.update_password(user, %{
password: new_password,
password_confirmation: new_password <> "oops",
current_password: wrong_password
})
assert {:error, %Ash.Error.Invalid{}} =
User.update_password(user, %{
password: new_password,
password_confirmation: new_password <> "oops",
current_password: wrong_password
})
10 replies
AEAsh Elixir
Created by Robert Graff on 8/3/2023 in #support
Why don't read actions filter by attributes?
I see. It's more about being more robust than a simple key/value filter. Thanks for helping me understand
13 replies
AEAsh Elixir
Created by Robert Graff on 8/3/2023 in #support
Why don't read actions filter by attributes?
This is a question more about the philosophy and intent, and less asking "how to?". Yes, we're currently using Ash.Query to filter. My question was "why?" because it seems like such a common use case. I think of using query as an escape hatch of sorts, because I really want my actions to define the intended usecases.
It's similar to how the GraphQL interface creates the input automatically from what's filterable. You don't have to define a read action with arguments for the filterable attributes.
13 replies
AEAsh Elixir
Created by Robert Graff on 7/28/2023 in #support
Key :editing_tenant not found
Would be nice to be able to configure tenant selection as a select input by setting providing tenant options in an assigns.
9 replies
AEAsh Elixir
Created by Robert Graff on 7/28/2023 in #support
Key :editing_tenant not found
Still can't select a tenant:
[error] GenServer #PID<0.4922.0> terminating
** (FunctionClauseError) no function clause matching in AshAdmin.PageLive.handle_event/3
(ash_admin 0.9.0) lib/ash_admin/pages/page_live.ex:284: AshAdmin.PageLive.handle_event("stop_editing_tenant", %{"value" => ""}, #Phoenix.LiveView.Socket<id: "phx-F3YupvdZ02N11DZB", endpoint: KickplanWeb.Endpoint, view: AshAdmin.PageLive, parent_pid: nil, root_pid: #PID<0.4922.0>, router: KickplanWeb.Router, assigns: %{__changed__: %{}, action: %Ash.Resource.Actions.Read{arguments: [], description: nil, filter: nil, get_by: nil, get?: false, manual: nil, metadata: [], modify_query: nil, name: :read, pagination: false, preparations: [], primary?: true, touches_resources: [], transaction?: false, type: :read}, action_type: :read, actor: nil, actor_api: nil, actor_paused: true, actor_resources: [], api: Kickplan.Environments, apis: [Kickplan.Organizations, Kickplan.Users, Kickplan.Environments], authorizing: false, flash: %{}, id: nil, live_action: :page, params: %{"action" => "read", "action_type" => "read", "api" => "Environments", "resource" => "Account", "route" => [], "table" => ""}, polymorphic_actions: nil, prefix: "/admin", primary_key: nil, record: nil, resource: Kickplan.Environments.Account, tab: nil, table: nil, tables: [], tenant: nil, url_path: "/admin"}, transport_pid: #PID<0.4910.0>, ...>)
(phoenix_live_view 0.19.5) lib/phoenix_live_view/channel.ex:401: anonymous fn/3 in Phoenix.LiveView.Channel.view_handle_event/3
(telemetry 1.2.1) /workspace/app/deps/telemetry/src/telemetry.erl:321: :telemetry.span/3
(phoenix_live_view 0.19.5) lib/phoenix_live_view/channel.ex:221: Phoenix.LiveView.Channel.handle_info/2
(stdlib 4.3) gen_server.erl:1123: :gen_server.try_dispatch/4
(stdlib 4.3) gen_server.erl:1200: :gen_server.handle_msg/6
(stdlib 4.3) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{topic: "lv:phx-F3YupvdZ02N11DZB", event: "event", payload: %{"event" => "stop_editing_tenant", "type" => "click", "value" => %{"value" => ""}}, ref: "7", join_ref: "4"}
[error] GenServer #PID<0.4922.0> terminating
** (FunctionClauseError) no function clause matching in AshAdmin.PageLive.handle_event/3
(ash_admin 0.9.0) lib/ash_admin/pages/page_live.ex:284: AshAdmin.PageLive.handle_event("stop_editing_tenant", %{"value" => ""}, #Phoenix.LiveView.Socket<id: "phx-F3YupvdZ02N11DZB", endpoint: KickplanWeb.Endpoint, view: AshAdmin.PageLive, parent_pid: nil, root_pid: #PID<0.4922.0>, router: KickplanWeb.Router, assigns: %{__changed__: %{}, action: %Ash.Resource.Actions.Read{arguments: [], description: nil, filter: nil, get_by: nil, get?: false, manual: nil, metadata: [], modify_query: nil, name: :read, pagination: false, preparations: [], primary?: true, touches_resources: [], transaction?: false, type: :read}, action_type: :read, actor: nil, actor_api: nil, actor_paused: true, actor_resources: [], api: Kickplan.Environments, apis: [Kickplan.Organizations, Kickplan.Users, Kickplan.Environments], authorizing: false, flash: %{}, id: nil, live_action: :page, params: %{"action" => "read", "action_type" => "read", "api" => "Environments", "resource" => "Account", "route" => [], "table" => ""}, polymorphic_actions: nil, prefix: "/admin", primary_key: nil, record: nil, resource: Kickplan.Environments.Account, tab: nil, table: nil, tables: [], tenant: nil, url_path: "/admin"}, transport_pid: #PID<0.4910.0>, ...>)
(phoenix_live_view 0.19.5) lib/phoenix_live_view/channel.ex:401: anonymous fn/3 in Phoenix.LiveView.Channel.view_handle_event/3
(telemetry 1.2.1) /workspace/app/deps/telemetry/src/telemetry.erl:321: :telemetry.span/3
(phoenix_live_view 0.19.5) lib/phoenix_live_view/channel.ex:221: Phoenix.LiveView.Channel.handle_info/2
(stdlib 4.3) gen_server.erl:1123: :gen_server.try_dispatch/4
(stdlib 4.3) gen_server.erl:1200: :gen_server.handle_msg/6
(stdlib 4.3) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{topic: "lv:phx-F3YupvdZ02N11DZB", event: "event", payload: %{"event" => "stop_editing_tenant", "type" => "click", "value" => %{"value" => ""}}, ref: "7", join_ref: "4"}
9 replies
AEAsh Elixir
Created by Robert Graff on 7/28/2023 in #support
Key :editing_tenant not found
Fixed most my issues with content-security-policy changes.
9 replies