ash_sqlite/test/load_test.exs

247 lines
6.8 KiB
Elixir

defmodule AshSqlite.Test.LoadTest do
use AshSqlite.RepoCase, async: false
alias AshSqlite.Test.{Comment, Post}
require Ash.Query
test "has_many relationships can be loaded" do
assert %Post{comments: %Ash.NotLoaded{type: :relationship}} =
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()
Comment
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()
results =
Post
|> Ash.Query.load(:comments)
|> Ash.read!()
assert [%Post{comments: [%{title: "match"}]}] = results
end
test "belongs_to relationships can be loaded" do
assert %Comment{post: %Ash.NotLoaded{type: :relationship}} =
comment =
Comment
|> Ash.Changeset.for_create(:create, %{})
|> Ash.create!()
Post
|> Ash.Changeset.for_create(:create, %{title: "match"})
|> Ash.Changeset.manage_relationship(:comments, [comment], type: :append_and_remove)
|> Ash.create!()
results =
Comment
|> Ash.Query.load(:post)
|> Ash.read!()
assert [%Comment{post: %{title: "match"}}] = results
end
test "many_to_many loads work" do
source_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "source"})
|> Ash.create!()
destination_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "destination"})
|> Ash.create!()
destination_post2 =
Post
|> Ash.Changeset.for_create(:create, %{title: "destination"})
|> Ash.create!()
source_post
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:linked_posts, [destination_post, destination_post2],
type: :append_and_remove
)
|> Ash.update!()
results =
source_post
|> Ash.load!(:linked_posts)
assert %{linked_posts: [%{title: "destination"}, %{title: "destination"}]} = results
end
test "many_to_many loads work when nested" do
source_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "source"})
|> Ash.create!()
destination_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "destination"})
|> Ash.create!()
source_post
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:linked_posts, [destination_post],
type: :append_and_remove
)
|> Ash.update!()
destination_post
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:linked_posts, [source_post], type: :append_and_remove)
|> Ash.update!()
results =
source_post
|> Ash.load!(linked_posts: :linked_posts)
assert %{linked_posts: [%{title: "destination", linked_posts: [%{title: "source"}]}]} =
results
end
describe "lateral join loads" do
# uncomment when lateral join is supported
# it does not necessarily have to be implemented *exactly* as lateral join
# test "parent references are resolved" do
# post1 =
# Post
# |> Ash.Changeset.new(%{title: "title"})
# |> Api.create!()
# post2 =
# Post
# |> Ash.Changeset.new(%{title: "title"})
# |> Api.create!()
# post2_id = post2.id
# post3 =
# Post
# |> Ash.Changeset.new(%{title: "no match"})
# |> Api.create!()
# assert [%{posts_with_matching_title: [%{id: ^post2_id}]}] =
# Post
# |> Ash.Query.load(:posts_with_matching_title)
# |> Ash.Query.filter(id == ^post1.id)
# |> Api.read!()
# assert [%{posts_with_matching_title: []}] =
# Post
# |> Ash.Query.load(:posts_with_matching_title)
# |> Ash.Query.filter(id == ^post3.id)
# |> Api.read!()
# end
# test "parent references work when joining for filters" do
# %{id: post1_id} =
# Post
# |> Ash.Changeset.new(%{title: "title"})
# |> Api.create!()
# post2 =
# Post
# |> Ash.Changeset.new(%{title: "title"})
# |> Api.create!()
# Post
# |> Ash.Changeset.new(%{title: "no match"})
# |> Api.create!()
# Post
# |> Ash.Changeset.new(%{title: "no match"})
# |> Api.create!()
# assert [%{id: ^post1_id}] =
# Post
# |> Ash.Query.filter(posts_with_matching_title.id == ^post2.id)
# |> Api.read!()
# end
# test "lateral join loads (loads with limits or offsets) are supported" do
# assert %Post{comments: %Ash.NotLoaded{type: :relationship}} =
# post =
# Post
# |> Ash.Changeset.new(%{title: "title"})
# |> Api.create!()
# Comment
# |> Ash.Changeset.new(%{title: "abc"})
# |> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
# |> Api.create!()
# Comment
# |> Ash.Changeset.new(%{title: "def"})
# |> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
# |> Api.create!()
# comments_query =
# Comment
# |> Ash.Query.limit(1)
# |> Ash.Query.sort(:title)
# results =
# Post
# |> Ash.Query.load(comments: comments_query)
# |> Api.read!()
# assert [%Post{comments: [%{title: "abc"}]}] = results
# comments_query =
# Comment
# |> Ash.Query.limit(1)
# |> Ash.Query.sort(title: :desc)
# results =
# Post
# |> Ash.Query.load(comments: comments_query)
# |> Api.read!()
# assert [%Post{comments: [%{title: "def"}]}] = results
# comments_query =
# Comment
# |> Ash.Query.limit(2)
# |> Ash.Query.sort(title: :desc)
# results =
# Post
# |> Ash.Query.load(comments: comments_query)
# |> Api.read!()
# assert [%Post{comments: [%{title: "def"}, %{title: "abc"}]}] = results
# end
test "loading many to many relationships on records works without loading its join relationship when using code interface" do
source_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "source"})
|> Ash.create!()
destination_post =
Post
|> Ash.Changeset.for_create(:create, %{title: "abc"})
|> Ash.create!()
destination_post2 =
Post
|> Ash.Changeset.for_create(:create, %{title: "def"})
|> Ash.create!()
source_post
|> Ash.Changeset.new()
|> Ash.Changeset.manage_relationship(:linked_posts, [destination_post, destination_post2],
type: :append_and_remove
)
|> Ash.update!()
assert %{linked_posts: [_, _]} = Post.get_by_id!(source_post.id, load: [:linked_posts])
end
end
end