Selecto.DynamicJoin (Selecto v0.3.16)
Handles dynamic join additions at runtime.
This module enables adding joins to a Selecto query that aren't defined in the domain configuration. This is useful for:
- Ad-hoc queries that need joins beyond the preconfigured domain
- Programmatic query building where joins depend on runtime conditions
- Parameterized joins where the same association needs different filters
examples
Examples
# Enable a predefined join from the domain
selecto |> Selecto.join(:category)
# Enable a join with specific type override
selecto |> Selecto.join(:orders, type: :inner)
# Add a parameterized instance of a join
selecto |> Selecto.join_parameterize(:products, "electronics", category: "Electronics")
# Add a custom join not in the domain
selecto |> Selecto.join(:audit_log,
source: "audit_logs",
on: [%{left: "id", right: "record_id"}],
type: :left
)
Link to this section Summary
Functions
Enable a join from the domain configuration or add a custom join.
Create a parameterized instance of an existing join.
Join with another Selecto query as a subquery.
Link to this section Functions
join(selecto, join_id, options \\ [])
Enable a join from the domain configuration or add a custom join.
parameters
Parameters
selecto- The Selecto structjoin_id- The join identifier (atom)options- Optional configuration overrides
options
Options
:type- Join type (:left, :inner, :right, :full). Default: :left:source- Source table name (required for custom joins):on- Join conditions as list of maps with :left and :right keys:owner_key- The key on the parent table:related_key- The key on the joined table:fields- Map of field configurations to expose from the joined table
examples
Examples
# Enable domain-configured join
selecto |> Selecto.DynamicJoin.join(:category)
# Custom join with explicit configuration
selecto |> Selecto.DynamicJoin.join(:audit_log,
source: "audit_logs",
on: [%{left: "id", right: "record_id"}],
type: :left,
fields: %{
action: %{type: :string},
created_at: %{type: :naive_datetime}
}
)
join_parameterize(selecto, join_id, parameter, options \\ [])
Create a parameterized instance of an existing join.
Parameterized joins allow the same association to be joined multiple times with different filter conditions, useful for queries like:
- "Products in Electronics category" vs "Products in Clothing category"
- "Active orders" vs "Cancelled orders"
- "Primary contacts" vs "Billing contacts"
parameters
Parameters
selecto- The Selecto structjoin_id- Base join identifier to parameterizeparameter- Unique parameter value to identify this instanceoptions- Filter conditions and options
options
Options
- All options from
join/3plus: - Any key that matches a filter in the join's filter config will be applied
examples
Examples
# Create parameterized join for electronics products
selecto
|> Selecto.DynamicJoin.join_parameterize(:products, "electronics",
category_id: 1,
active: true
)
|> Selecto.select(["products:electronics.product_name"])
# Multiple parameterized instances
selecto
|> Selecto.DynamicJoin.join_parameterize(:orders, "active", status: "active")
|> Selecto.DynamicJoin.join_parameterize(:orders, "completed", status: "completed")
|> Selecto.select([
"orders:active.total as active_total",
"orders:completed.total as completed_total"
])
join_subquery(selecto, join_id, join_selecto, options \\ [])
Join with another Selecto query as a subquery.
This creates a join using a separate Selecto query as the right side, enabling complex subquery joins.
parameters
Parameters
selecto- The main Selecto structjoin_id- Identifier for this joinjoin_selecto- The Selecto struct to use as subqueryoptions- Join configuration
options
Options
:type- Join type (:left, :inner, :right, :full). Default: :left:on- Join conditions referencing the subquery alias
examples
Examples
# Create a subquery for aggregated data
order_totals = Selecto.configure(order_domain, connection)
|> Selecto.select(["customer_id", {:sum, "total", as: "total_spent"}])
|> Selecto.group_by(["customer_id"])
# Join to main query
selecto
|> Selecto.DynamicJoin.join_subquery(:customer_totals, order_totals,
on: [%{left: "customer_id", right: "customer_id"}]
)
|> Selecto.select(["name", "customer_totals.total_spent"])