-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
1) test Thing.create! create works without associating other things (ThingTest) test/thing_test.exs:20 ** (Ash.Error.Unknown) Bread Crumbs: > Exception raised in: Things.get_by_id Unknown Error * ** (RuntimeError) Error while building reference: all_other_things.associated_at (ash_sql 0.2.38) lib/expr.ex:1796: AshSql.Expr.default_dynamic_expr/6 (ash_sql 0.2.38) lib/expr.ex:88: AshSql.Expr.default_dynamic_expr/6
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
{ | ||
"attributes": [ | ||
{ | ||
"allow_nil?": false, | ||
"default": "nil", | ||
"generated?": false, | ||
"primary_key?": false, | ||
"references": null, | ||
"size": null, | ||
"source": "role", | ||
"type": "text" | ||
}, | ||
{ | ||
"allow_nil?": true, | ||
"default": "nil", | ||
"generated?": false, | ||
"primary_key?": false, | ||
"references": null, | ||
"size": null, | ||
"source": "was_cancelled_at", | ||
"type": "utc_datetime" | ||
}, | ||
{ | ||
"allow_nil?": false, | ||
"default": "nil", | ||
"generated?": false, | ||
"primary_key?": true, | ||
"references": { | ||
"deferrable": false, | ||
"destination_attribute": "id", | ||
"destination_attribute_default": null, | ||
"destination_attribute_generated": null, | ||
"index?": false, | ||
"match_type": null, | ||
"match_with": null, | ||
"multitenancy": { | ||
"attribute": null, | ||
"global": null, | ||
"strategy": null | ||
}, | ||
"name": "co_authored_posts_author_id_fkey", | ||
"on_delete": null, | ||
"on_update": null, | ||
"primary_key?": true, | ||
"schema": "public", | ||
"table": "authors" | ||
}, | ||
"size": null, | ||
"source": "author_id", | ||
"type": "uuid" | ||
}, | ||
{ | ||
"allow_nil?": false, | ||
"default": "nil", | ||
"generated?": false, | ||
"primary_key?": true, | ||
"references": { | ||
"deferrable": false, | ||
"destination_attribute": "id", | ||
"destination_attribute_default": null, | ||
"destination_attribute_generated": null, | ||
"index?": false, | ||
"match_type": null, | ||
"match_with": null, | ||
"multitenancy": { | ||
"attribute": null, | ||
"global": null, | ||
"strategy": null | ||
}, | ||
"name": "co_authored_posts_post_id_fkey", | ||
"on_delete": null, | ||
"on_update": null, | ||
"primary_key?": true, | ||
"schema": "public", | ||
"table": "posts" | ||
}, | ||
"size": null, | ||
"source": "post_id", | ||
"type": "uuid" | ||
} | ||
], | ||
"base_filter": null, | ||
"check_constraints": [], | ||
"custom_indexes": [], | ||
"custom_statements": [], | ||
"has_create_action": true, | ||
"hash": "E1F2AC3AED1987928E3A2446584C268EC54D0BCA616D81A495F4AB26E3999444", | ||
"identities": [], | ||
"multitenancy": { | ||
"attribute": null, | ||
"global": null, | ||
"strategy": null | ||
}, | ||
"repo": "Elixir.AshPostgres.TestRepo", | ||
"schema": null, | ||
"table": "co_authored_posts" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
defmodule AshPostgres.TestRepo.Migrations.MigrateResources44 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(:co_authored_posts, primary_key: false) do | ||
add(:role, :text, null: false) | ||
add(:was_cancelled_at, :utc_datetime) | ||
|
||
add( | ||
:author_id, | ||
references(:authors, | ||
column: :id, | ||
name: "co_authored_posts_author_id_fkey", | ||
type: :uuid, | ||
prefix: "public" | ||
), | ||
primary_key: true, | ||
null: false | ||
) | ||
|
||
add( | ||
:post_id, | ||
references(:posts, | ||
column: :id, | ||
name: "co_authored_posts_post_id_fkey", | ||
type: :uuid, | ||
prefix: "public" | ||
), | ||
primary_key: true, | ||
null: false | ||
) | ||
end | ||
end | ||
|
||
def down do | ||
drop(constraint(:co_authored_posts, "co_authored_posts_author_id_fkey")) | ||
|
||
drop(constraint(:co_authored_posts, "co_authored_posts_post_id_fkey")) | ||
|
||
drop(table(:co_authored_posts)) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
defmodule AshPostgres.ManyToManyExprTest do | ||
use AshPostgres.RepoCase, async: false | ||
|
||
alias AshPostgres.Test.Author | ||
alias AshPostgres.Test.CoAuthorPost | ||
alias AshPostgres.Test.Post | ||
|
||
require Ash.Query | ||
|
||
setup ctx do | ||
main_author = | ||
if ctx[:main_author?], | ||
do: create_author(), | ||
else: nil | ||
|
||
co_authors = | ||
if ctx[:co_authors], | ||
do: 1..ctx[:co_authors] | ||
|> Stream.map(& | ||
Author | ||
|> Ash.Changeset.for_create(:create, %{first_name: "John #{&1}", last_name: "Doe"}) | ||
|> Ash.create!() | ||
) | ||
|> Enum.into([]), | ||
else: [] | ||
|
||
%{ | ||
main_author: main_author, | ||
co_authors: co_authors, | ||
} | ||
end | ||
|
||
def create_author(params \\ %{first_name: "John", last_name: "Doe"}) do | ||
Author | ||
|> Ash.Changeset.for_create(:create, params) | ||
|> Ash.create!() | ||
end | ||
|
||
def create_post(author) do | ||
Post | ||
|> Ash.Changeset.for_create(:create, %{title: "Post by #{author.first_name}"}) | ||
|> Ash.create!() | ||
end | ||
|
||
def create_co_author_post(author, post, role) do | ||
CoAuthorPost | ||
|> Ash.Changeset.for_create(:create, %{author_id: author.id, post_id: post.id, role: role}) | ||
|> Ash.create!() | ||
end | ||
|
||
def get_author!(author_id) do | ||
Author | ||
|> Ash.Query.new() | ||
|> Ash.Query.filter(id == ^author_id) | ||
|> Ash.Query.load([:all_co_authored_posts, :cancelled_co_authored_posts, :editor_of, :writer_of]) | ||
|> Ash.read_one!() | ||
end | ||
|
||
def get_co_author_post!(a_id, p_id) do | ||
CoAuthorPost | ||
|> Ash.Query.new() | ||
|> Ash.Query.filter(author_id == ^a_id and post_id == ^p_id) | ||
|> Ash.read_one!() | ||
end | ||
|
||
def get_post!(post_id) do | ||
Post.get_by_id!(post_id, load: [:co_author_posts, :co_authors_unfiltered, :co_authors]) | ||
end | ||
|
||
def cancel(author, post) do | ||
get_co_author_post!(author.id, post.id) | ||
|> CoAuthorPost.cancel() | ||
end | ||
|
||
def uncancel(author, post) do | ||
get_co_author_post!(author.id, post.id) | ||
|> CoAuthorPost.uncancel() | ||
end | ||
|
||
describe "manual join-resource insertion" do | ||
@tag main_author?: true | ||
@tag co_authors: 3 | ||
test "filter on many_to_many relationship using parent works as expected - basic", | ||
%{ | ||
main_author: main_author, | ||
co_authors: co_authors, | ||
} do | ||
post = create_post(main_author) | ||
|
||
[first_ca, second_ca, third_ca] = co_authors | ||
|
||
# Add first co-author | ||
create_co_author_post(first_ca, post, :editor) | ||
|
||
first_ca = get_author!(first_ca.id) | ||
post = get_post!(post.id) | ||
|
||
assert Enum.count(post.co_authors) == 1 | ||
assert Enum.count(first_ca.all_co_authored_posts) == 1 | ||
assert Enum.count(first_ca.editor_of) == 1 | ||
assert Enum.count(first_ca.writer_of) == 0 | ||
assert Enum.count(first_ca.cancelled_co_authored_posts) == 0 | ||
|
||
# Add second co-author | ||
create_co_author_post(second_ca, post, :writer) | ||
|
||
second_ca = get_author!(second_ca.id) | ||
post = get_post!(post.id) | ||
|
||
assert Enum.count(post.co_authors) == 2 | ||
assert Enum.count(second_ca.all_co_authored_posts) == 1 | ||
assert Enum.count(second_ca.editor_of) == 0 | ||
assert Enum.count(second_ca.writer_of) == 1 | ||
assert Enum.count(second_ca.cancelled_co_authored_posts) == 0 | ||
Check warning on line 114 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 114 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
|
||
# Add third co-author | ||
create_co_author_post(third_ca, post, :proof_reader) | ||
|
||
third_ca = get_author!(third_ca.id) | ||
post = get_post!(post.id) | ||
|
||
assert Enum.count(post.co_authors) == 3 | ||
assert Enum.count(third_ca.all_co_authored_posts) == 1 | ||
assert Enum.count(third_ca.editor_of) == 0 | ||
Check warning on line 124 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 124 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
assert Enum.count(third_ca.writer_of) == 0 | ||
Check warning on line 125 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 125 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
assert Enum.count(third_ca.cancelled_co_authored_posts) == 0 | ||
Check warning on line 126 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 126 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
end | ||
|
||
@tag main_author?: true | ||
@tag co_authors: 4 | ||
test "filter on many_to_many relationship using parent works as expected - cancelled", | ||
%{ | ||
main_author: main_author, | ||
co_authors: co_authors, | ||
} do | ||
first_post = create_post(main_author) | ||
second_post = create_post(main_author) | ||
|
||
[first_ca, second_ca, third_ca, fourth_ca] = co_authors | ||
|
||
# Add first co-author | ||
create_co_author_post(first_ca, first_post, :editor) | ||
create_co_author_post(first_ca, second_post, :writer) | ||
|
||
first_ca = get_author!(first_ca.id) | ||
first_post = get_post!(first_post.id) | ||
|
||
assert Enum.count(first_post.co_authors) == 1 | ||
assert Enum.count(first_post.co_authors_unfiltered) == 1 | ||
|
||
assert Enum.count(first_ca.all_co_authored_posts) == 2 | ||
assert Enum.count(first_ca.editor_of) == 1 | ||
assert Enum.count(first_ca.writer_of) == 1 | ||
assert Enum.count(first_ca.cancelled_co_authored_posts) == 0 | ||
Check warning on line 154 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 154 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
|
||
# Add second co-author | ||
create_co_author_post(second_ca, first_post, :proof_reader) | ||
create_co_author_post(second_ca, second_post, :writer) | ||
|
||
second_ca = get_author!(second_ca.id) | ||
first_post = get_post!(first_post.id) | ||
second_post = get_post!(second_post.id) | ||
|
||
assert Enum.count(second_post.co_authors) == 2 | ||
assert Enum.count(second_post.co_authors_unfiltered) == 2 | ||
|
||
assert Enum.count(second_ca.all_co_authored_posts) == 2 | ||
assert Enum.count(second_ca.editor_of) == 0 | ||
Check warning on line 168 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 168 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
assert Enum.count(second_ca.writer_of) == 1 | ||
assert Enum.count(second_ca.cancelled_co_authored_posts) == 0 | ||
Check warning on line 170 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 170 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
|
||
# Add third co-author | ||
create_co_author_post(third_ca, first_post, :proof_reader) | ||
create_co_author_post(third_ca, second_post, :proof_reader) | ||
cancel(third_ca, second_post) | ||
|
||
third_ca = get_author!(third_ca.id) | ||
first_post = get_post!(first_post.id) | ||
second_post = get_post!(second_post.id) | ||
|
||
assert Enum.count(first_post.co_authors) == 3 | ||
assert Enum.count(first_post.co_authors_unfiltered) == 3 | ||
assert Enum.count(second_post.co_authors) == 2 | ||
assert Enum.count(second_post.co_authors_unfiltered) == 3 | ||
|
||
assert Enum.count(third_ca.all_co_authored_posts) == 2 | ||
assert Enum.count(third_ca.editor_of) == 0 | ||
Check warning on line 187 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 187 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
assert Enum.count(third_ca.writer_of) == 0 | ||
Check warning on line 188 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 188 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
assert Enum.count(third_ca.cancelled_co_authored_posts) == 1 | ||
|
||
# Add fourth co-author | ||
create_co_author_post(fourth_ca, first_post, :proof_reader) | ||
create_co_author_post(fourth_ca, second_post, :editor) | ||
cancel(fourth_ca, first_post) | ||
cancel(fourth_ca, second_post) | ||
|
||
fourth_ca = get_author!(fourth_ca.id) | ||
first_post = get_post!(first_post.id) | ||
second_post = get_post!(second_post.id) | ||
|
||
assert Enum.count(first_post.co_authors) == 3 | ||
assert Enum.count(first_post.co_authors_unfiltered) == 4 | ||
assert Enum.count(second_post.co_authors) == 2 | ||
assert Enum.count(second_post.co_authors_unfiltered) == 4 | ||
|
||
assert Enum.count(fourth_ca.all_co_authored_posts) == 2 | ||
assert Enum.count(fourth_ca.editor_of) == 1 | ||
assert Enum.count(fourth_ca.writer_of) == 0 | ||
Check warning on line 208 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (14) / mix credo --strict
Check warning on line 208 in test/many_to_many_expr_test.exs GitHub Actions / ash-ci (15) / mix credo --strict
|
||
assert Enum.count(fourth_ca.cancelled_co_authored_posts) == 2 | ||
end | ||
end | ||
end |