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

Link to this function

join(selecto, join_id, options \\ [])

@spec join(Selecto.t(), atom(), keyword()) :: Selecto.t()

Enable a join from the domain configuration or add a custom join.

parameters

Parameters

  • selecto - The Selecto struct
  • join_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}
  }
)
Link to this function

join_parameterize(selecto, join_id, parameter, options \\ [])

@spec join_parameterize(Selecto.t(), atom(), String.t() | atom(), keyword()) ::
  Selecto.t()

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 struct
  • join_id - Base join identifier to parameterize
  • parameter - Unique parameter value to identify this instance
  • options - Filter conditions and options

options

Options

  • All options from join/3 plus:
  • 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"
  ])
Link to this function

join_subquery(selecto, join_id, join_selecto, options \\ [])

@spec join_subquery(Selecto.t(), atom(), Selecto.t(), keyword()) :: Selecto.t()

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 struct
  • join_id - Identifier for this join
  • join_selecto - The Selecto struct to use as subquery
  • options - 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"])