mirror of
https://github.com/ash-project/ash_postgres.git
synced 2024-09-20 05:23:18 +12:00
improvement: support parent
in sort expressions
This commit is contained in:
parent
75208a70f8
commit
342920a3c4
4 changed files with 78 additions and 5 deletions
|
@ -552,12 +552,22 @@ defmodule AshPostgres.DataLayer do
|
|||
|> default_bindings(resource, context)
|
||||
|
||||
case context[:data_layer][:lateral_join_source] do
|
||||
{_, [{%{resource: resource}, _, _, _} | _]} ->
|
||||
{_, [{%{resource: resource}, _, _, _} | rest]} ->
|
||||
parent =
|
||||
resource
|
||||
|> resource_to_query(nil)
|
||||
|> default_bindings(resource, context)
|
||||
|
||||
parent =
|
||||
case rest do
|
||||
[{resource, _, _, %{name: join_relationship_name}} | _] ->
|
||||
binding_data = %{type: :inner, path: [join_relationship_name], source: resource}
|
||||
add_binding(parent, binding_data)
|
||||
|
||||
_ ->
|
||||
parent
|
||||
end
|
||||
|
||||
ash_bindings =
|
||||
data_layer_query.__ash_bindings__
|
||||
|> Map.put(:parent_bindings, Map.put(parent.__ash_bindings__, :parent?, true))
|
||||
|
|
|
@ -1055,14 +1055,15 @@ defmodule AshPostgres.Expr do
|
|||
type
|
||||
) do
|
||||
parent? = Map.get(bindings.parent_bindings, :parent_is_parent_as?, true)
|
||||
new_bindings = Map.put(bindings.parent_bindings, :parent?, parent?)
|
||||
|
||||
do_dynamic_expr(
|
||||
%{
|
||||
query
|
||||
| __ash_bindings__: Map.put(bindings.parent_bindings, :parent?, parent?)
|
||||
| __ash_bindings__: new_bindings
|
||||
},
|
||||
expr,
|
||||
bindings,
|
||||
new_bindings,
|
||||
embedded?,
|
||||
type
|
||||
)
|
||||
|
@ -1607,7 +1608,8 @@ defmodule AshPostgres.Expr do
|
|||
end
|
||||
end
|
||||
|
||||
defp set_parent_path(query, parent) do
|
||||
@doc false
|
||||
def set_parent_path(query, parent) do
|
||||
# This is a stupid name. Its actually the path we *remove* when stepping up a level. I.e the child's path
|
||||
Map.update!(query, :__ash_bindings__, fn ash_bindings ->
|
||||
ash_bindings
|
||||
|
|
19
lib/sort.ex
19
lib/sort.ex
|
@ -20,6 +20,7 @@ defmodule AshPostgres.Sort do
|
|||
%{
|
||||
resource: resource,
|
||||
aggregates: %{},
|
||||
parent_stack: query.__ash_bindings__[:parent_resources] || [],
|
||||
calculations: %{},
|
||||
public?: false
|
||||
}
|
||||
|
@ -84,14 +85,30 @@ defmodule AshPostgres.Sort do
|
|||
|> Ash.Filter.hydrate_refs(%{
|
||||
resource: resource,
|
||||
aggregates: query.__ash_bindings__.aggregate_defs,
|
||||
parent_stack: query.__ash_bindings__[:parent_resources] || [],
|
||||
calculations: %{},
|
||||
public?: false
|
||||
})
|
||||
|> Ash.Filter.move_to_relationship_path(relationship_path)
|
||||
|> case do
|
||||
{:ok, expr} ->
|
||||
bindings =
|
||||
if query.__ash_bindings__[:parent_bindings] do
|
||||
Map.update!(query.__ash_bindings__, :parent_bindings, fn parent ->
|
||||
Map.put(parent, :parent_is_parent_as?, false)
|
||||
end)
|
||||
else
|
||||
query.__ash_bindings__
|
||||
end
|
||||
|
||||
expr =
|
||||
AshPostgres.Expr.dynamic_expr(query, expr, query.__ash_bindings__, false, type)
|
||||
AshPostgres.Expr.dynamic_expr(
|
||||
query,
|
||||
expr,
|
||||
bindings,
|
||||
false,
|
||||
type
|
||||
)
|
||||
|
||||
{:cont, {:ok, query_expr ++ [{order, expr}]}}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ defmodule AshPostgres.SortTest do
|
|||
alias AshPostgres.Test.{Api, Comment, Post, PostLink}
|
||||
|
||||
require Ash.Query
|
||||
require Ash.Sort
|
||||
import Ash.Expr
|
||||
|
||||
test "multi-column sorts work" do
|
||||
Post
|
||||
|
@ -181,4 +183,46 @@ defmodule AshPostgres.SortTest do
|
|||
|> Ash.Query.sort(:c_times_p)
|
||||
|> Api.read!()
|
||||
end
|
||||
|
||||
test "calculations can sort on expressions" do
|
||||
post1 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "aaa", score: 0})
|
||||
|> Api.create!()
|
||||
|
||||
post2 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "bbb", score: 1})
|
||||
|> Api.create!()
|
||||
|
||||
post3 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "ccc", score: 0})
|
||||
|> Api.create!()
|
||||
|
||||
PostLink
|
||||
|> Ash.Changeset.new()
|
||||
|> Ash.Changeset.manage_relationship(:source_post, post1, type: :append)
|
||||
|> Ash.Changeset.manage_relationship(:destination_post, post3, type: :append)
|
||||
|> Api.create!()
|
||||
|
||||
PostLink
|
||||
|> Ash.Changeset.new()
|
||||
|> Ash.Changeset.manage_relationship(:source_post, post2, type: :append)
|
||||
|> Ash.Changeset.manage_relationship(:destination_post, post2, type: :append)
|
||||
|> Api.create!()
|
||||
|
||||
PostLink
|
||||
|> Ash.Changeset.new()
|
||||
|> Ash.Changeset.manage_relationship(:source_post, post3, type: :append)
|
||||
|> Ash.Changeset.manage_relationship(:destination_post, post1, type: :append)
|
||||
|> Api.create!()
|
||||
|
||||
posts_query =
|
||||
Ash.Query.sort(Post, Ash.Sort.expr_sort(source(post_links.state)))
|
||||
|
||||
Post
|
||||
|> Ash.Query.load(linked_posts: posts_query)
|
||||
|> Api.read!()
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue