Guidance on Generators

Need to implement a generator for a resource action that makes use of after_action hooks (organization > establishment > establishment_user) This is my chain of actions:
# organization.ex
create :create_organization do
argument :establishment, :map, allow_nil?: false

change relate_actor(:owner)

change after_action(fn changeset, org, context ->
case Lamashka.Establishments.create_establishment(
changeset.arguments.establishment,
actor: context.actor,
tenant: org,
context: %{
accessing_from: %{
source: __MODULE__,
name: :establishments
}
}
) do
{:ok, _establishment} -> {:ok, org}
{:error, error} -> {:error, Ash.Error.set_path(error, :establishment)}
end
end)
end
# organization.ex
create :create_organization do
argument :establishment, :map, allow_nil?: false

change relate_actor(:owner)

change after_action(fn changeset, org, context ->
case Lamashka.Establishments.create_establishment(
changeset.arguments.establishment,
actor: context.actor,
tenant: org,
context: %{
accessing_from: %{
source: __MODULE__,
name: :establishments
}
}
) do
{:ok, _establishment} -> {:ok, org}
{:error, error} -> {:error, Ash.Error.set_path(error, :establishment)}
end
end)
end
# establishment.ex
create :create_establishment do
change after_action(fn _changeset, est, context ->
Lamashka.Establishments.add_establishment_user!(
%{user_id: context.actor.id, role: :admin},
tenant: est,
context: %{
accessing_from: %{
source: __MODULE__,
name: :establishment_users
}
}
)

{:ok, est}
end)
end
# establishment.ex
create :create_establishment do
change after_action(fn _changeset, est, context ->
Lamashka.Establishments.add_establishment_user!(
%{user_id: context.actor.id, role: :admin},
tenant: est,
context: %{
accessing_from: %{
source: __MODULE__,
name: :establishment_users
}
}
)

{:ok, est}
end)
end
# establishment_user.ex
create :add_establishment_user do
accept [:user_id, :role]
end
# establishment_user.ex
create :add_establishment_user do
accept [:user_id, :role]
end
This is what I'm trying so far without success
def org(opts \\ []) do
changeset_generator(
Organization,
:create_organization,
defaults: [
name: "Organization",
establishment: %{
name: "Establishment",
address: "Address"
}
],
overrides: opts,
actor: opts[:actor]
)
end
def org(opts \\ []) do
changeset_generator(
Organization,
:create_organization,
defaults: [
name: "Organization",
establishment: %{
name: "Establishment",
address: "Address"
}
],
overrides: opts,
actor: opts[:actor]
)
end
Invalid Error
* Invalid value provided for role: does not exist.
Invalid Error
* Invalid value provided for role: does not exist.
3 Replies
Joan Gavelán
Joan GavelánOP4mo ago
Mmm I just run it on IEX and the generator seems to be working, it is just failing on tests
1) test require_tenant/2 loads tenant from session (LamashkaWeb.TenantAuthTest)
test/lamashka_web/tenant_auth_test.exs:9
** (Ash.Error.Invalid)
Bread Crumbs:
> Error returned from: Lamashka.Organizations.Organization.create_organization

Invalid Error

* Invalid value provided for role: does not exist.

(ash 3.5.25) lib/ash/error/changes/invalid_attribute.ex:4: Ash.Error.Changes.InvalidAttribute."exception (overridable 2)"/1
(elixir 1.18.3) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash_postgres 2.6.8) lib/data_layer.ex:2371: AshPostgres.DataLayer.handle_raised_error/4
(ash_postgres 2.6.8) lib/data_layer.ex:2169: AshPostgres.DataLayer.create/2
1) test require_tenant/2 loads tenant from session (LamashkaWeb.TenantAuthTest)
test/lamashka_web/tenant_auth_test.exs:9
** (Ash.Error.Invalid)
Bread Crumbs:
> Error returned from: Lamashka.Organizations.Organization.create_organization

Invalid Error

* Invalid value provided for role: does not exist.

(ash 3.5.25) lib/ash/error/changes/invalid_attribute.ex:4: Ash.Error.Changes.InvalidAttribute."exception (overridable 2)"/1
(elixir 1.18.3) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash_postgres 2.6.8) lib/data_layer.ex:2371: AshPostgres.DataLayer.handle_raised_error/4
(ash_postgres 2.6.8) lib/data_layer.ex:2169: AshPostgres.DataLayer.create/2
What could be the reason?
ZachDaniel
ZachDaniel4mo ago
You may need to set a nil value for that argument it will generate random inputs otherwise i.e defaults: [arg: nil]
Joan Gavelán
Joan GavelánOP4mo ago
The role isn't passed as an argument, is manually being set on the create_establishment action
create :create_establishment do
change after_action(fn _changeset, est, context ->
Lamashka.Establishments.add_establishment_user!(
%{user_id: context.actor.id, role: :admin}, # here
tenant: est,
context: %{
accessing_from: %{
source: __MODULE__,
name: :establishment_users
}
}
)

{:ok, est}
end)
end
create :create_establishment do
change after_action(fn _changeset, est, context ->
Lamashka.Establishments.add_establishment_user!(
%{user_id: context.actor.id, role: :admin}, # here
tenant: est,
context: %{
accessing_from: %{
source: __MODULE__,
name: :establishment_users
}
}
)

{:ok, est}
end)
end
I'm using an enum table for roles btw, could that be the reason? Maybe the generator does not know of the records available in the role table? Yep, it wasn't a problem related to Ash but more about my lack of understanding of the testing environment, so sorry. Closing this.

Did you find this page helpful?