Myrmyr
Myrmyr
AEAsh Elixir
Created by Myrmyr on 9/29/2023 in #support
Forbid all but one field using field policies
Hello, I need to forbid Anonymous actor access to all fields but id and status. Basically it's needed for some calulcations but we don't want him to have access to any other data. So I've tried using policies like this:
field_policies do
field_policy :status do
authorize_if always()
end

field_policy :* do
forbid_if Checks.IsAnonymousActor
authorize_if always()
end
end
field_policies do
field_policy :status do
authorize_if always()
end

field_policy :* do
forbid_if Checks.IsAnonymousActor
authorize_if always()
end
end
But this seems to not be working, probably because for status filed Ash checks policies from both status and :*. Is there any way to achieve that?
4 replies
AEAsh Elixir
Created by Myrmyr on 7/20/2023 in #support
Ash dropping FilterCheck if there's `authorize_if always()`
Hi, I've got a resource that in it's action has:
authorize_if MyApp.FilterByActorId
authorize_if always()
authorize_if MyApp.FilterByActorId
authorize_if always()
Previously there were other checks instead of always() but we've loosened our constraints. When we've changed it to always() the FilterByActorID stopped applying My question is, is this the intended behaviour or is it a bug?
18 replies
AEAsh Elixir
Created by Myrmyr on 6/27/2023 in #support
Updating Spark to 1.1.17 breaks Ash.Flow transaction DSL
Ash version: 2.10.2 Spark latest working version: 1.1.16 Spark version that breaks: 1.1.17 Example code:
defmodule MyApp.Flows.ExampleFlow do
@moduledoc false

use Ash.Flow

flow do
api MyApp.Api

argument :example_arg, :map do
allow_nil? false
end

returns :some_transaction
end

steps do
# This works
custom :custom_step_that_do_not_break, MyApp.Flows.Steps.SimpleReturn do
input %{
return: arg(:example_arg)
}
end

transaction :some_transaction, MyApp.SomeEntity do
# This does not work
custom :custom_step_that_breaks, MyApp.Flows.Steps.SimpleReturn do
input %{
return: arg(:example_arg)
}
end
end
end
end
defmodule MyApp.Flows.ExampleFlow do
@moduledoc false

use Ash.Flow

flow do
api MyApp.Api

argument :example_arg, :map do
allow_nil? false
end

returns :some_transaction
end

steps do
# This works
custom :custom_step_that_do_not_break, MyApp.Flows.Steps.SimpleReturn do
input %{
return: arg(:example_arg)
}
end

transaction :some_transaction, MyApp.SomeEntity do
# This does not work
custom :custom_step_that_breaks, MyApp.Flows.Steps.SimpleReturn do
input %{
return: arg(:example_arg)
}
end
end
end
end
Error message:
== Compilation error in file lib/my_app/flows/example_flow.ex ==
** (CompileError) lib/my_app/flows/example_flow.ex:24: undefined function custom/3 (there is no such import)
(stdlib 4.1.1) lists.erl:1462: :lists.mapfoldl_1/3
(ash 2.10.2) expanding macro: Ash.Flow.Dsl.Steps.Transaction.transaction/3
== Compilation error in file lib/my_app/flows/example_flow.ex ==
** (CompileError) lib/my_app/flows/example_flow.ex:24: undefined function custom/3 (there is no such import)
(stdlib 4.1.1) lists.erl:1462: :lists.mapfoldl_1/3
(ash 2.10.2) expanding macro: Ash.Flow.Dsl.Steps.Transaction.transaction/3
Didn't know whether this should be reported to Spark or Ash so I'm reporting it here.
3 replies
AEAsh Elixir
Created by Myrmyr on 5/9/2023 in #support
Prevent action's changes from being run on `AshPhoenix.Form.validate`
Hello, I have an resource A that has a filed let's say capacity , belongs_to relationship to B resource and create action that has a change LoadDefaultFromRelationship . This change basically fetches the capacity from B resource if none was given in the create action params for A. The problem with such approach is that every time we invoke the AshPhoenix.Form.validate it makes a query to the database for this default value. Is there any way to prevent this change being run on AshPhoenix.Form.validate but still apply on create action?
7 replies
AEAsh Elixir
Created by Myrmyr on 4/3/2023 in #support
`Ash.Type.NewType` defines multiple GraphQL types with the same name.
I have the following custom type
defmodule MyApp.Types.DayOfWeek do
@moduledoc false

use Ash.Type.NewType,
subtype_of: :atom,
constraints: [one_of: [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]]

def graphql_input_type(_), do: :day_of_week
def graphql_type, do: :day_of_week
def graphql_type(_), do: :day_of_week
end
defmodule MyApp.Types.DayOfWeek do
@moduledoc false

use Ash.Type.NewType,
subtype_of: :atom,
constraints: [one_of: [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]]

def graphql_input_type(_), do: :day_of_week
def graphql_type, do: :day_of_week
def graphql_type(_), do: :day_of_week
end
That is used in two resources
defmodule ResourceA do
...
attributes do
...
attribute :days_of_week, {:array, MyApp.Types.DayOfWeek}
end
end


defmodule ResourceB do
...
attributes do
...
attribute :day_of_week, MyApp.Types.DayOfWeek}
end

relationships do
belongs_to :a_resource, ResourceA, allow_nil?: false
end
end
defmodule ResourceA do
...
attributes do
...
attribute :days_of_week, {:array, MyApp.Types.DayOfWeek}
end
end


defmodule ResourceB do
...
attributes do
...
attribute :day_of_week, MyApp.Types.DayOfWeek}
end

relationships do
belongs_to :a_resource, ResourceA, allow_nil?: false
end
end
Also I've defined a Scalar and imported it to schema
scalar :day_of_week do
parse(&parse_day_of_week/1)
serialize(& &1)
end

defp parse_day_of_week(%Absinthe.Blueprint.Input.String{value: value}) do
case MyApp.Types.DayOfWeek.cast_input(value, []) do
{:ok, value} -> {:ok, value}
_ -> :error
end
end
scalar :day_of_week do
parse(&parse_day_of_week/1)
serialize(& &1)
end

defp parse_day_of_week(%Absinthe.Blueprint.Input.String{value: value}) do
case MyApp.Types.DayOfWeek.cast_input(value, []) do
{:ok, value} -> {:ok, value}
_ -> :error
end
end
20 replies
AEAsh Elixir
Created by Myrmyr on 3/16/2023 in #support
Embed `has_one` relationship into resource
Let's say I have a resource A. It has relationship:
relationships do
has_many :a_version, Ash.Api.AVersion do
sort created_at: :desc
end
end
relationships do
has_many :a_version, Ash.Api.AVersion do
sort created_at: :desc
end
end
which holds some fields that should be versioned if any changes happen, it has at least one :a_version Let's say the AVersion has the a :price attribute. We can define the manual fake "has_one" relationship, by making a query that takes the latest version of AVersion. Now, here's question. Is there any way to embed the fields from the latest AVersion from the fake "has_one" manual relationship into A so that they can be: - Accessed at top-level like A.price - Loaded automatically as if they were attributes of the A itself?
38 replies
AEAsh Elixir
Created by Myrmyr on 2/9/2023 in #support
Ash stopped working with ExMachina. Ash 2.5.10
Hello, I've been using Ash with ExMachina successfully up to this point. Recently I've wanted to upgrade Ash from 2.5.9 to 2.6.0, alongside AshPostgres from 1.3.3 to 1.3.8. I've tested combinations of different Ash and AshPostgres combinations to narrow down the issue. It appears to be caused by Ash 2.5.10. Specifically this commit https://github.com/ash-project/ash/commit/2787b5074b8b339057af6f0bc4ee3db5abf7c60d Our factory:
defmodule MyApp.Factory do
@moduledoc false
use ExMachina.Ecto, repo: MyApp.Repo

def resource_factory do
%MyApp.Resource{
id: Ecto.UUID.generate(),
name: sequence(:name, &"Resource #{&1}"),
...
}
end
defmodule MyApp.Factory do
@moduledoc false
use ExMachina.Ecto, repo: MyApp.Repo

def resource_factory do
%MyApp.Resource{
id: Ecto.UUID.generate(),
name: sequence(:name, &"Resource #{&1}"),
...
}
end
When I try to do insert(:resource, some_field: "some_value) I get the following error
** (UndefinedFunctionError) function Ash.NotLoaded.__schema__/0 is undefined or private
(ash 2.6.0) Ash.NotLoaded.__schema__()
iex:1: (file)
** (UndefinedFunctionError) function Ash.NotLoaded.__schema__/0 is undefined or private
(ash 2.6.0) Ash.NotLoaded.__schema__()
iex:1: (file)
Is there any possibility to bring back the support for ExMachina?
29 replies