diff --git a/lib/ash/filter/filter.ex b/lib/ash/filter/filter.ex index bf1a50f75..b1dc43aa4 100644 --- a/lib/ash/filter/filter.ex +++ b/lib/ash/filter/filter.ex @@ -471,6 +471,18 @@ defmodule Ash.Filter do end {fields, value} -> + multitenancy_attribute = Ash.Resource.Info.multitenancy_attribute(resource) + fields = Enum.reject(fields, fn key -> key == multitenancy_attribute end) + + {keyval?, value} = + case fields do + [field] when not keyval? -> + {true, [{field, value}]} + + _ -> + {keyval?, value} + end + if keyval? do with :error <- get_keys(value, fields, resource), :error <- get_identity_filter(resource, id) do diff --git a/test/filter/multitenancy_test.exs b/test/filter/multitenancy_test.exs new file mode 100644 index 000000000..7102beea7 --- /dev/null +++ b/test/filter/multitenancy_test.exs @@ -0,0 +1,62 @@ +defmodule Ash.Test.MultitenancyTest do + @moduledoc false + use ExUnit.Case, async: true + + alias Ash.Test.Domain, as: Domain + + defmodule MultiTenant do + use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets + + multitenancy do + strategy :attribute + attribute :owner + end + + attributes do + attribute :id, :integer, primary_key?: true, allow_nil?: false, public?: true + attribute :owner, :integer, primary_key?: true, allow_nil?: false, public?: true + end + + actions do + default_accept :* + defaults [:read, :create] + end + end + + test "reading an object doesn't require multitenancy attribute in the primary key" do + MultiTenant + |> Ash.Changeset.for_create(:create, %{id: 1000, owner: 1}) + |> Ash.create!(tenant: 1) + + MultiTenant + |> Ash.get!(1000, tenant: 1) + end + + defmodule NonMultiTenant do + use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets + + attributes do + attribute :id, :integer, primary_key?: true, allow_nil?: false, public?: true + attribute :owner, :integer, primary_key?: true, allow_nil?: false, public?: true + end + + actions do + default_accept :* + defaults [:read, :create] + end + end + + test "reading an object without multitenancy requires attribute in the primary key" do + NonMultiTenant + |> Ash.Changeset.for_create(:create, %{id: 1000, owner: 1}) + |> Ash.create!() + + ExUnit.Assertions.assert_raise(Ash.Error.Invalid, fn -> + NonMultiTenant + |> Ash.get!(1000) + end) + + NonMultiTenant + |> Ash.get!(%{id: 1000, owner: 1}) + end +end