diff --git a/lib/ash/code_interface.ex b/lib/ash/code_interface.ex index 407e4b64..b33a63e1 100644 --- a/lib/ash/code_interface.ex +++ b/lib/ash/code_interface.ex @@ -31,8 +31,18 @@ defmodule Ash.CodeInterface do {:argument, argument} end - if !field.allow_nil? do - raise "Code interface for #{action.name} has optional argument #{key} but it is not optional" + cond do + field.allow_nil? && !(field.name in Map.get(action, :require_attributes, [])) -> + :ok + + field.name in Map.get(action, :allow_nil_input, []) -> + :ok + + !(field.name in Map.get(action, :accept, [])) -> + :ok + + true -> + raise "Code interface for #{action.name} has optional argument #{key} but it is not optional" end default = diff --git a/lib/ash/engine/engine.ex b/lib/ash/engine/engine.ex index 7572e1a3..efaf2a9a 100644 --- a/lib/ash/engine/engine.ex +++ b/lib/ash/engine/engine.ex @@ -255,6 +255,7 @@ defmodule Ash.Engine do def must_be_local?(request) do [request.resource | request.touches_resources || []] |> Enum.filter(& &1) + |> Enum.filter(&is_atom/1) |> Enum.any?(fn resource -> (Ash.DataLayer.data_layer_can?(resource, :transact) && Ash.DataLayer.in_transaction?(resource)) || diff --git a/lib/ash/resource.ex b/lib/ash/resource.ex index 93d11225..7f42cc50 100644 --- a/lib/ash/resource.ex +++ b/lib/ash/resource.ex @@ -113,6 +113,10 @@ defmodule Ash.Resource do end if api = Ash.Resource.Info.define_interface_for(__MODULE__) do + if api == __MODULE__ do + raise "code_interface.define_for should be set to the API module you want it to call, not the resource." + end + require Ash.CodeInterface Ash.CodeInterface.define_interface(api, __MODULE__) end diff --git a/lib/ash/resource/interface.ex b/lib/ash/resource/interface.ex index 7489f352..cfa6f2e3 100644 --- a/lib/ash/resource/interface.ex +++ b/lib/ash/resource/interface.ex @@ -8,11 +8,11 @@ defmodule Ash.Resource.Interface do defmacro __using__(_) do quote bind_quoted: [], generated: true do - if Ash.Resource.Info.define_interface_for(__MODULE__) do + if define_for = Ash.Resource.Info.define_interface_for(__MODULE__) do require Ash.CodeInterface Ash.CodeInterface.define_interface( - Ash.Resource.Info.define_interface_for(__MODULE__), + define_for, __MODULE__ ) end