improvement: add binding() expression

This commit is contained in:
Zach Daniel 2024-07-15 10:25:39 -04:00
parent 6f7d163da8
commit ab97b2947b
4 changed files with 40 additions and 1 deletions

View file

@ -785,7 +785,8 @@ defmodule AshPostgres.DataLayer do
functions = [
AshPostgres.Functions.Like,
AshPostgres.Functions.ILike
AshPostgres.Functions.ILike,
AshPostgres.Functions.Binding
]
functions =

9
lib/functions/binding.ex Normal file
View file

@ -0,0 +1,9 @@
defmodule AshPostgres.Functions.Binding do
@moduledoc """
Refers to the current table binding.
"""
use Ash.Query.Function, name: :binding
def args, do: [[]]
end

View file

@ -41,6 +41,21 @@ defmodule AshPostgres.SqlImplementation do
{:ok, Ecto.Query.dynamic(fragment("'[]'::jsonb")), acc}
end
def expr(query, %AshPostgres.Functions.Binding{}, _bindings, _embedded?, acc, _type) do
binding = AshSql.Bindings.get_binding(
query.__ash_bindings__.resource,
[],
query,
[:left, :inner, :root]
)
if is_nil(binding) do
raise "Error while constructing explicit `binding()` reference."
end
{:ok, Ecto.Query.dynamic([{^binding, row}], row), acc}
end
def expr(
query,
%like{arguments: [arg1, arg2], embedded?: pred_embedded?},

View file

@ -800,6 +800,20 @@ defmodule AshPostgres.CalculationTest do
|> Ash.read_one!()
end
test "binding() can be used to refer to the current binding in a fragment" do
post =
Post
|> Ash.Changeset.for_create(:create, %{})
|> Ash.create!()
post_id = post.id
assert [%{id: ^post_id}] =
Post
|> Ash.Query.filter(fragment("(?).id", binding()) == type(^post.id, :uuid))
|> Ash.read!()
end
test "exists with a relationship that has a filtered read action works" do
post =
Post