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,75 @@
# SPDX-FileCopyrightText: 2019 ash_postgres contributors <https://github.com/ash-project/ash_postgres/graphs/contributors>
#
# SPDX-License-Identifier: MIT

defmodule AshPostgres.TestRepo.Migrations.AddNotificationRecipients do
use Ecto.Migration

def up do
create table(:notification_recipients, primary_key: false) do
add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true)
add(:order, :bigint)

add(
:post_id,
references(:posts,
column: :id,
name: "notification_recipients_post_id_fkey",
type: :uuid,
prefix: "public"
)
)

add(
:comment_id,
references(:comments,
column: :id,
name: "notification_recipients_comment_id_fkey",
type: :uuid,
prefix: "public"
)
)

add(
:user_id,
references(:users,
column: :id,
name: "notification_recipients_user_id_fkey",
type: :uuid,
prefix: "public"
)
)

add(
:staff_group_id,
references(:staff_group,
column: :id,
name: "notification_recipients_staff_group_id_fkey",
type: :uuid,
prefix: "public"
)
)
end

create(
unique_index(:notification_recipients, ["post_id", "user_id"],
name: "notification_recipients_post_user_index",
where: "(post_id IS NOT NULL) AND (user_id IS NOT NULL)"
)
)
end

def down do
drop_if_exists(
unique_index(:notification_recipients, ["post_id", "user_id"],
name: "notification_recipients_post_user_index"
)
)

drop(constraint(:notification_recipients, "notification_recipients_post_id_fkey"))
drop(constraint(:notification_recipients, "notification_recipients_comment_id_fkey"))
drop(constraint(:notification_recipients, "notification_recipients_user_id_fkey"))
drop(constraint(:notification_recipients, "notification_recipients_staff_group_id_fkey"))
drop(table(:notification_recipients))
end
end
35 changes: 35 additions & 0 deletions test/load_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule AshPostgres.Test.LoadTest do
alias AshPostgres.Test.{
Author,
Comment,
NotificationRecipient,
Post,
PostFollower,
Record,
Expand Down Expand Up @@ -234,6 +235,40 @@ defmodule AshPostgres.Test.LoadTest do
assert length(post.first_3_followers) == 2
end

test "many_to_many can sort on a polymorphic partial identity join relationship" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "a"})
|> Ash.create!()

followers =
for i <- 0..2 do
User
|> Ash.Changeset.for_create(:create, %{name: "user#{i}", is_active: true})
|> Ash.create!()
end

followers
|> Enum.zip([2, 0, 1])
|> Enum.each(fn {follower, order} ->
NotificationRecipient
|> Ash.Changeset.for_create(:create, %{
order: order,
post_id: post.id,
user_id: follower.id
})
|> Ash.create!()
end)

[post] =
Post
|> Ash.Query.for_read(:read, %{})
|> Ash.Query.load(:sorted_notification_users)
|> Ash.read!()

assert Enum.map(post.sorted_notification_users, & &1.name) == ["user1", "user2", "user0"]
end

test "many_to_many loads work when nested" do
source_post =
Post
Expand Down
1 change: 1 addition & 0 deletions test/support/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ defmodule AshPostgres.Test.Domain do
resource(AshPostgres.Test.Permalink)
resource(AshPostgres.Test.Record)
resource(AshPostgres.Test.PostFollower)
resource(AshPostgres.Test.NotificationRecipient)
resource(AshPostgres.Test.StatefulPostFollower)
resource(AshPostgres.Test.PostWithEmptyUpdate)
resource(AshPostgres.Test.DbPoint)
Expand Down
56 changes: 56 additions & 0 deletions test/support/resources/notification_recipient.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: 2019 ash_postgres contributors <https://github.com/ash-project/ash_postgres/graphs/contributors>
#
# SPDX-License-Identifier: MIT

defmodule AshPostgres.Test.NotificationRecipient do
@moduledoc false
use Ash.Resource,
domain: AshPostgres.Test.Domain,
data_layer: AshPostgres.DataLayer

postgres do
table "notification_recipients"
repo AshPostgres.TestRepo

identity_wheres_to_sql(post_user: "(post_id IS NOT NULL) AND (user_id IS NOT NULL)")
end

identities do
identity(:post_user, [:post_id, :user_id],
where: expr(not is_nil(post_id) and not is_nil(user_id))
)
end

actions do
default_accept(:*)

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

attributes do
uuid_primary_key(:id)
attribute(:order, :integer, public?: true)
end

relationships do
belongs_to :post, AshPostgres.Test.Post do
public?(true)
allow_nil?(true)
end

belongs_to :comment, AshPostgres.Test.Comment do
public?(true)
allow_nil?(true)
end

belongs_to :user, AshPostgres.Test.User do
public?(true)
allow_nil?(true)
end

belongs_to :staff_group, AshPostgres.Test.StaffGroup do
public?(true)
allow_nil?(true)
end
end
end
14 changes: 14 additions & 0 deletions test/support/resources/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,11 @@ defmodule AshPostgres.Test.Post do

has_many(:post_followers, AshPostgres.Test.PostFollower)

has_many :user_notification_recipients, AshPostgres.Test.NotificationRecipient do
filter(expr(not is_nil(user_id)))
sort(order: :asc)
end

# For testing join_relationship limit inheritance
has_many :top_three_post_followers, AshPostgres.Test.PostFollower do
sort(order: :asc)
Expand Down Expand Up @@ -918,6 +923,15 @@ defmodule AshPostgres.Test.Post do
sort: [Ash.Sort.expr_sort(parent(post_followers.order), :integer)]
)

many_to_many(:sorted_notification_users, AshPostgres.Test.User,
public?: true,
through: AshPostgres.Test.NotificationRecipient,
join_relationship: :user_notification_recipients,
source_attribute_on_join_resource: :post_id,
destination_attribute_on_join_resource: :user_id,
sort: [Ash.Sort.expr_sort(parent(user_notification_recipients.order), :integer)]
)

many_to_many :tags, AshPostgres.Test.Tag do
public?(true)
through(AshPostgres.Test.PostTag)
Expand Down
Loading