mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 13:03:02 +12:00
improvement: add tenant option to Ash.Seed.seed! (#1230)
This commit is contained in:
parent
1f34fa9191
commit
6b964b9384
2 changed files with 129 additions and 10 deletions
|
@ -49,10 +49,7 @@ defmodule Ash.Seed do
|
|||
Map.put(acc, key, value)
|
||||
end)
|
||||
|
||||
seed!(
|
||||
resource,
|
||||
input
|
||||
)
|
||||
seed!(resource, input)
|
||||
end
|
||||
|
||||
def seed!(records) when is_list(records) do
|
||||
|
@ -63,20 +60,25 @@ defmodule Ash.Seed do
|
|||
Performs a direct call to the data layer of a resource with the provided input.
|
||||
|
||||
If a list is provided as input, then you will get back that many results.
|
||||
|
||||
To set a tenant, use the tenant option.
|
||||
"""
|
||||
def seed!(resource, input) when is_list(input) do
|
||||
Enum.map(input, &seed!(resource, &1))
|
||||
|
||||
def seed!(resource, input, opts \\ [])
|
||||
|
||||
def seed!(resource, input, opts) when is_list(input) do
|
||||
Enum.map(input, &seed!(resource, &1, opts))
|
||||
end
|
||||
|
||||
def seed!(resource, %resource{} = input) do
|
||||
def seed!(resource, %resource{} = input, _opts) do
|
||||
seed!(input)
|
||||
end
|
||||
|
||||
def seed!(resource, %other{}) do
|
||||
def seed!(resource, %other{}, _opts) do
|
||||
raise "Cannot seed #{inspect(resource)} with an input of type #{inspect(other)}"
|
||||
end
|
||||
|
||||
def seed!(%resource{} = record, input) when is_map(input) do
|
||||
def seed!(%resource{} = record, input, opts) when is_map(input) do
|
||||
attrs =
|
||||
resource
|
||||
|> Ash.Resource.Info.attributes()
|
||||
|
@ -100,6 +102,8 @@ defmodule Ash.Seed do
|
|||
|> change_attributes(input)
|
||||
|> change_relationships(input)
|
||||
|> Ash.Changeset.set_defaults(:create, true)
|
||||
|> Ash.Changeset.set_tenant(opts[:tenant])
|
||||
|> maybe_set_attribute_tenant()
|
||||
|> create_via_data_layer()
|
||||
|> case do
|
||||
{:ok, result, _, _} ->
|
||||
|
@ -110,7 +114,7 @@ defmodule Ash.Seed do
|
|||
end
|
||||
end
|
||||
|
||||
def seed!(resource, input) when is_map(input) do
|
||||
def seed!(resource, input, opts) when is_map(input) do
|
||||
attr_input =
|
||||
input
|
||||
|> Map.new(fn {key, value} ->
|
||||
|
@ -126,6 +130,8 @@ defmodule Ash.Seed do
|
|||
|> change_attributes(attr_input)
|
||||
|> change_relationships(input)
|
||||
|> Ash.Changeset.set_defaults(:create, true)
|
||||
|> Ash.Changeset.set_tenant(opts[:tenant])
|
||||
|> maybe_set_attribute_tenant()
|
||||
|> create_via_data_layer()
|
||||
|> case do
|
||||
{:ok, result, _, _} ->
|
||||
|
@ -315,4 +321,17 @@ defmodule Ash.Seed do
|
|||
Map.put(input, field, field_value)
|
||||
)
|
||||
end
|
||||
|
||||
defp maybe_set_attribute_tenant(changeset) do
|
||||
if changeset.tenant &&
|
||||
Ash.Resource.Info.multitenancy_strategy(changeset.resource) == :attribute do
|
||||
attribute = Ash.Resource.Info.multitenancy_attribute(changeset.resource)
|
||||
{m, f, a} = Ash.Resource.Info.multitenancy_parse_attribute(changeset.resource)
|
||||
attribute_value = apply(m, f, [changeset.to_tenant | a])
|
||||
|
||||
Ash.Changeset.force_change_attribute(changeset, attribute, attribute_value)
|
||||
else
|
||||
changeset
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,79 @@ defmodule Ash.Test.SeedTest do
|
|||
require Ash.Query
|
||||
alias Ash.Test.Domain, as: Domain
|
||||
|
||||
defmodule Tenant do
|
||||
use Ash.Resource,
|
||||
domain: Domain,
|
||||
data_layer: Ash.DataLayer.Ets
|
||||
|
||||
ets do
|
||||
private?(true)
|
||||
end
|
||||
|
||||
actions do
|
||||
default_accept :*
|
||||
defaults [:read, :destroy, create: :*, update: :*]
|
||||
end
|
||||
|
||||
attributes do
|
||||
uuid_primary_key :id
|
||||
attribute :name, :string, public?: true, allow_nil?: false
|
||||
end
|
||||
end
|
||||
|
||||
defmodule ContextUser do
|
||||
use Ash.Resource,
|
||||
domain: Domain,
|
||||
data_layer: Ash.DataLayer.Ets
|
||||
|
||||
ets do
|
||||
private?(true)
|
||||
end
|
||||
|
||||
multitenancy do
|
||||
strategy :context
|
||||
end
|
||||
|
||||
actions do
|
||||
default_accept :*
|
||||
defaults [:read, :destroy, create: :*, update: :*]
|
||||
end
|
||||
|
||||
attributes do
|
||||
uuid_primary_key :id
|
||||
attribute :name, :string, public?: true, allow_nil?: false
|
||||
end
|
||||
end
|
||||
|
||||
defmodule AttributeUser do
|
||||
use Ash.Resource,
|
||||
domain: Domain,
|
||||
data_layer: Ash.DataLayer.Ets
|
||||
|
||||
ets do
|
||||
private?(true)
|
||||
end
|
||||
|
||||
multitenancy do
|
||||
strategy :attribute
|
||||
attribute :tenant_id
|
||||
end
|
||||
|
||||
actions do
|
||||
default_accept :*
|
||||
defaults [:read, :destroy, create: :*, update: :*]
|
||||
end
|
||||
|
||||
attributes do
|
||||
uuid_primary_key :id
|
||||
attribute :name, :string, public?: true, allow_nil?: false
|
||||
end
|
||||
|
||||
relationships do
|
||||
belongs_to :tenant, Ash.Test.SeedTest.Tenant
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Author do
|
||||
@moduledoc false
|
||||
use Ash.Resource,
|
||||
|
@ -269,5 +342,32 @@ defmodule Ash.Test.SeedTest do
|
|||
assert Enum.count(Ash.read!(Rating)) == 2
|
||||
assert Enum.count(Ash.read!(Author)) == 1
|
||||
end
|
||||
|
||||
test "context multitenancy works" do
|
||||
tenant = seed!(%Tenant{name: "Tenant"})
|
||||
tenant_id = tenant.id
|
||||
|
||||
user = seed!(ContextUser, %{name: "User"}, tenant: tenant_id)
|
||||
user_id = user.id
|
||||
|
||||
assert {:ok, %ContextUser{id: ^user_id}} = Ash.get(ContextUser, user_id, tenant: tenant_id)
|
||||
|
||||
assert {:error, %{errors: [%Ash.Error.Query.NotFound{}]}} =
|
||||
Ash.get(ContextUser, user_id, tenant: "random")
|
||||
end
|
||||
|
||||
test "attribute multitenancy works" do
|
||||
tenant = seed!(%Tenant{name: "Tenant"})
|
||||
tenant_id = tenant.id
|
||||
|
||||
user = seed!(AttributeUser, %{name: "User"}, tenant: tenant_id)
|
||||
user_id = user.id
|
||||
|
||||
assert {:ok, %AttributeUser{id: ^user_id}} =
|
||||
Ash.get(AttributeUser, user_id, tenant: tenant_id)
|
||||
|
||||
assert {:error, %{errors: [%Ash.Error.Query.NotFound{}]}} =
|
||||
Ash.get(AttributeUser, user_id, tenant: "random")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue