Skip to content

Commit bae0cca

Browse files
committed
fix: don’t require multitenancy attribute in get
Signed-off-by: Adam Tharani <adamtharani@me.com>
1 parent fdea4ae commit bae0cca

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

lib/ash/filter/filter.ex

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,9 @@ defmodule Ash.Filter do
448448
:error # not enough information
449449
"""
450450
def get_filter(resource, id) do
451+
multitenancy_attribute = Ash.Resource.Info.multitenancy_attribute(resource)
451452
primary_key = Ash.Resource.Info.primary_key(resource)
453+
452454
keyval? = Keyword.keyword?(id) || is_map(id)
453455

454456
case {primary_key, id} do
@@ -471,6 +473,17 @@ defmodule Ash.Filter do
471473
end
472474

473475
{fields, value} ->
476+
fields = Enum.reject(fields, fn key -> key == multitenancy_attribute end)
477+
478+
{keyval?, value} =
479+
case fields do
480+
[field] when not keyval? ->
481+
{true, [{field, value}]}
482+
483+
_ ->
484+
{keyval?, value}
485+
end
486+
474487
if keyval? do
475488
with :error <- get_keys(value, fields, resource),
476489
:error <- get_identity_filter(resource, id) do

test/filter/multitenancy_test.exs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
defmodule Ash.Test.MultitenancyTest do
2+
@moduledoc false
3+
use ExUnit.Case, async: true
4+
5+
alias Ash.Test.Domain, as: Domain
6+
7+
defmodule MultiTenant do
8+
use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets
9+
10+
multitenancy do
11+
strategy :attribute
12+
attribute :owner
13+
end
14+
15+
attributes do
16+
attribute :id, :integer, primary_key?: true, allow_nil?: false, public?: true
17+
attribute :owner, :integer, primary_key?: true, allow_nil?: false, public?: true
18+
end
19+
20+
actions do
21+
default_accept :*
22+
defaults [:read, :create]
23+
end
24+
end
25+
26+
test "reading an object doesn't require multitenancy attribute in the primary key" do
27+
MultiTenant
28+
|> Ash.Changeset.for_create(:create, %{id: 1000, owner: 1})
29+
|> Ash.create!(tenant: 1)
30+
31+
MultiTenant
32+
|> Ash.get!(1000, tenant: 1)
33+
end
34+
35+
defmodule NonMultiTenant do
36+
use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets
37+
38+
attributes do
39+
attribute :id, :integer, primary_key?: true, allow_nil?: false, public?: true
40+
attribute :owner, :integer, primary_key?: true, allow_nil?: false, public?: true
41+
end
42+
43+
actions do
44+
default_accept :*
45+
defaults [:read, :create]
46+
end
47+
end
48+
49+
test "reading an object without multitenancy requires attribute in the primary key" do
50+
NonMultiTenant
51+
|> Ash.Changeset.for_create(:create, %{id: 1000, owner: 1})
52+
|> Ash.create!()
53+
54+
ExUnit.Assertions.assert_raise(Ash.Error.Invalid, fn ->
55+
NonMultiTenant
56+
|> Ash.get!(1000)
57+
end)
58+
59+
NonMultiTenant
60+
|> Ash.get!(%{id: 1000, owner: 1})
61+
end
62+
end

0 commit comments

Comments
 (0)