FatEcto.Query.Dynamics.Builder (FatEcto v1.4.0)

View Source

Builds Ecto dynamic expressions from a structured query map. Used by FatDynamicsBuildable for dynamic-only use cases.

Summary

Functions

build(query_map, override_callback \\ nil, overrideable_fields \\ nil, join_filters \\ nil, field_aliases \\ nil)

@spec build(map(), function() | nil, list() | nil, map() | nil, map() | nil) ::
  Ecto.Query.dynamic_expr()

Builds an Ecto dynamic query from a JSON-like structure.

Parameters

  • query_map - A map of field => value or field => %{operator => value}
  • override_callback - Optional callback for overrideable fields
  • overrideable_fields - List of fields that use the override callback
  • join_filters - Optional map of field_name => binding_atom for join filter fields
  • field_aliases - Optional map of api_name => schema_field_atom for aliased fields

Join Filters

When join_filters is provided, any field in that map will use JoinOperatorApplier to generate dynamics with named bindings instead of the default table binding.

# Example join_filters:
%{"subject_id" => :classifications, "grade_id" => :classifications}

# This causes subject_id filters to generate:
dynamic([classifications: joined], joined.subject_id == ^value)

Field Aliases

When field_aliases is provided, API field names are resolved to actual schema field names before building dynamics. This allows using different names in the API than in the database schema, which is useful when joined tables have conflicting field names.

# Example field_aliases:
%{"author_name" => :name, "subject_name" => :name}

Examples

iex> import Ecto.Query
...> query = FatEcto.Query.Dynamics.Builder.build(%{
...>   "$OR" => [
...>     %{"name" => "John"},
...>     %{"phone" => nil},
...>     %{"age" => %{"$GT" => 30}}
...>   ]
...> })
iex> inspect(query)
"dynamic([q], q.name == ^\"John\" or is_nil(q.phone) or q.age > ^30)"