Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"gen_random_uuid()\")",
"generated?": false,
"precision": null,
"primary_key?": true,
"references": null,
"scale": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "\"active\"",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": null,
"scale": null,
"size": null,
"source": "state",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": {
"deferrable": false,
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"index?": true,
"match_type": null,
"match_with": null,
"multitenancy": {
"attribute": null,
"global": false,
"strategy": "context"
},
"name": "non_multitenant_post_multitenant_links_source_id_fkey",
"on_delete": "delete",
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "multitenant_posts"
},
"scale": null,
"size": null,
"source": "source_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": {
"deferrable": false,
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"index?": true,
"match_type": null,
"match_with": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "non_multitenant_post_multitenant_links_dest_id_fkey",
"on_delete": "delete",
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "posts"
},
"scale": null,
"size": null,
"source": "dest_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "F19D22A316D43A64BF2F1E052F545346BD0BCBC660E8EF559D1D4D73D8969A4D",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "non_multitenant_post_multitenant_links_unique_link_index",
"keys": [
{
"type": "atom",
"value": "source_id"
},
{
"type": "atom",
"value": "dest_id"
}
],
"name": "unique_link",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": false,
"strategy": "context"
},
"repo": "Elixir.AshPostgres.TestRepo",
"schema": null,
"table": "non_multitenant_post_multitenant_links"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources7 do
@moduledoc """
Updates resources based on their most recent snapshots.

This file was autogenerated with `mix ash_postgres.generate_migrations`
"""

use Ecto.Migration

def up do
create table(:non_multitenant_post_multitenant_links, primary_key: false, prefix: prefix()) do
add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true)
add(:state, :text, default: "active")

add(
:source_id,
references(:multitenant_posts,
column: :id,
name: "non_multitenant_post_multitenant_links_source_id_fkey",
type: :uuid,
prefix: prefix(),
on_delete: :delete_all
),
null: false
)

add(
:dest_id,
references(:posts,
column: :id,
name: "non_multitenant_post_multitenant_links_dest_id_fkey",
type: :uuid,
prefix: "public",
on_delete: :delete_all
),
null: false
)
end

create(index(:non_multitenant_post_multitenant_links, [:source_id]))

create(index(:non_multitenant_post_multitenant_links, [:dest_id]))

create(
unique_index(:non_multitenant_post_multitenant_links, [:source_id, :dest_id],
name: "non_multitenant_post_multitenant_links_unique_link_index"
)
)
end

def down do
drop_if_exists(
unique_index(:non_multitenant_post_multitenant_links, [:source_id, :dest_id],
name: "non_multitenant_post_multitenant_links_unique_link_index"
)
)

drop_if_exists(index(:non_multitenant_post_multitenant_links, [:dest_id]))

drop_if_exists(index(:non_multitenant_post_multitenant_links, [:source_id]))

drop(
constraint(
:non_multitenant_post_multitenant_links,
"non_multitenant_post_multitenant_links_source_id_fkey"
)
)

drop(
constraint(
:non_multitenant_post_multitenant_links,
"non_multitenant_post_multitenant_links_dest_id_fkey"
)
)

drop(table(:non_multitenant_post_multitenant_links, prefix: prefix()))
end
end
20 changes: 19 additions & 1 deletion test/multitenancy_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use AshPostgres.RepoCase, async: false

require Ash.Query
alias AshPostgres.MultitenancyTest.{CompositeKeyPost, NamedOrg, Org, Post, User}
alias AshPostgres.MultitenancyTest.{CompositeKeyPost, NamedOrg, Org, Post, User, NonMultitenantPostMultitenantLink}
alias AshPostgres.Test.Post, as: GlobalPost

setup do
Expand Down Expand Up @@ -226,6 +226,24 @@
)
end

test "loading non multitenant resource across a many_to_many works", %{org1: org1} do
post = Post
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|> Ash.Changeset.set_tenant(org1)
|> Ash.create!()

GlobalPost
|> Ash.Changeset.for_create(:create, %{title: "fred"})
|> Ash.create!()

NonMultitenantPostMultitenantLink
|> Ash.Changeset.for_create(:create, %{source_id: post.id, dest_id: global_post.id}, tenant: org1)
|> Ash.create!()

post |> Ash.load!([:linked_non_multitenant_posts_through_multitenant_link], tenant: org1) |> IO.inspect()

Check warning on line 243 in test/multitenancy_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci (16) / mix credo --strict

There should be no calls to `IO.inspect/1`.

Check warning on line 243 in test/multitenancy_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci (14) / mix credo --strict

There should be no calls to `IO.inspect/1`.

Check warning on line 243 in test/multitenancy_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci (15) / mix credo --strict

There should be no calls to `IO.inspect/1`.
end


test "manage_relationship from context multitenant resource to attribute multitenant resource doesn't raise an error" do
org = Org |> Ash.Changeset.new() |> Ash.create!()
user = User |> Ash.Changeset.new() |> Ash.create!()
Expand Down
1 change: 1 addition & 0 deletions test/support/multitenancy/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule AshPostgres.MultitenancyTest.Domain do
resource(AshPostgres.MultitenancyTest.NonMultitenantPostLink)
resource(AshPostgres.MultitenancyTest.CrossTenantPostLink)
resource(AshPostgres.MultitenancyTest.CompositeKeyPost)
resource(AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink)
end

authorization do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do
@moduledoc false
use Ash.Resource,
domain: AshPostgres.MultitenancyTest.Domain,
data_layer: AshPostgres.DataLayer

postgres do
table "non_multitenant_post_multitenant_links"
repo AshPostgres.TestRepo

references do
reference :source, on_delete: :delete, index?: true
reference :dest, on_delete: :delete, index?: true
end
end

multitenancy do
strategy(:context)
end

actions do
default_accept(:*)

defaults([:create, :read, :update, :destroy])
end

identities do
identity(:unique_link, [:source_id, :dest_id])
end

attributes do
uuid_primary_key :id

attribute :state, :atom do
public?(true)
constraints(one_of: [:active, :archived])
default(:active)
end
end

relationships do
belongs_to :source, AshPostgres.MultitenancyTest.Post do
public? true
allow_nil? false
end

belongs_to :dest, AshPostgres.Test.Post do
public? true
allow_nil? false
end
end
end
11 changes: 11 additions & 0 deletions test/support/multitenancy/resources/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,23 @@ defmodule AshPostgres.MultitenancyTest.Post do

# has_many(:non_multitenant_post_links, AshPostgres.MultitenancyTest.NonMultitenantPostLink)

has_many :non_multitenant_post_multitenant_links, AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do
destination_attribute :source_id
end

many_to_many :linked_non_multitenant_posts, AshPostgres.Test.Post do
through(AshPostgres.MultitenancyTest.NonMultitenantPostLink)
join_relationship(:non_multitenant_post_links)
source_attribute_on_join_resource(:source_id)
destination_attribute_on_join_resource(:dest_id)
end

many_to_many :linked_non_multitenant_posts_through_multitenant_link, AshPostgres.Test.Post do
through(AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink)
join_relationship(:non_multitenant_post_links_through_multitenant_link)
source_attribute_on_join_resource(:source_id)
destination_attribute_on_join_resource(:dest_id)
end
end

calculations do
Expand Down
Loading