Drops.Relation.Plugins.Reading (drops_relation v0.1.0)

View Source

Plugin that provides reading operations for relation modules.

This plugin adds Ecto.Repo-like functions for querying data, organized into two main groups:

Query API

These functions execute queries immediately and return results. They delegate directly to the corresponding Ecto.Repo functions with automatic repository and relation configuration:

Composable Query API

These functions build composable query operations that can be chained together and executed later. They return relation structs that can be further composed:

  • restrict/2 - Add WHERE conditions to filter records
  • order/2 - Add ORDER BY clauses to sort records
  • preload/2 - Add association preloading

Key Differences

Query API functions execute immediately:

users = MyApp.Users.all()                    # Returns list of users
user = MyApp.Users.get(1)                    # Returns user or nil
count = MyApp.Users.count()                  # Returns integer

Composable Query API functions return composable relations:

query = MyApp.Users.restrict(active: true)   # Returns relation struct
query = MyApp.Users.order(query, :name)      # Returns relation struct
users = MyApp.Users.all(query)               # Execute and return results

Examples

iex> user = MyApp.Users.get(1)
iex> user.name
"John Doe"
iex> user.email
"john@example.com"
...>
iex> MyApp.Users.all() |> length()
3
...>
iex> user = MyApp.Users.get_by(email: "john@example.com")
iex> user.name
"John Doe"
...>
iex> MyApp.Users.count()
3
...>
iex> MyApp.Users.aggregate(:avg, :age)
Decimal.new("30.0000000000000000")

iex> active_users = MyApp.Users.restrict(active: true)
...>   |> MyApp.Users.order(:name)
...>   |> MyApp.Users.all()
...>
iex> length(active_users)
2
iex> hd(active_users).name
"Jane Smith"

Summary

Composable Query API

Orders the query by the given specification.

Orders the given queryable by the specified criteria.

Preloads associations in queries.

Restricts the query with the given conditions.

Restricts the given queryable with the specified conditions.

Query API

Calculates the given aggregate.

Fetches all records from the relation.

Fetches all records from a composable relation query.

Fetches all records matching the given clauses.

Returns the average value for the given field.

Returns the average value for the given field from a composable relation query.

Checks out a connection for the duration of the function.

Returns the count of records.

Returns the count of records from a composable relation query.

Deletes all entries matching the given query.

Checks if any entry matches the given query.

Returns the first record.

Returns the first record from a composable relation query.

Fetches a single record by its primary key.

Fetches a single record by its primary key, raising if not found.

Gets a single record by the given clauses.

Gets a single record by the given clauses, raises if not found.

Returns true if the current process is inside a transaction.

Returns the last record.

Returns the last record from a composable relation query.

Returns the maximum value for the given field.

Returns the maximum value for the given field from a composable relation query.

Returns the minimum value for the given field.

Returns the minimum value for the given field from a composable relation query.

Fetches a single result from the query.

Fetches a single result from a composable relation query.

Fetches a single result from the query, raises if not found or more than one.

Fetches a single result from a composable relation query, raises if not found or more than one.

Returns a lazy enumerable that emits all entries from the data store.

Returns the sum of values for the given field.

Returns the sum of values for the given field from a composable relation query.

Runs the given function or Ecto.Multi inside a transaction.

Updates all entries matching the given query with the given values.

Types

order_spec()

@type order_spec() :: atom() | [atom()] | keyword()

preload_spec()

@type preload_spec() :: atom() | [atom()] | keyword()

queryable()

@type queryable() :: Ecto.Queryable.t()

relation()

@type relation() :: %{queryable: Ecto.Queryable.t(), opts: keyword()}

restrict_spec()

@type restrict_spec() :: keyword()

Composable Query API

order(spec, opts)

@spec order(
  order_spec(),
  keyword()
) :: relation()

Orders the query by the given specification.

This function creates a composable query operation that adds ORDER BY clauses to sort records. It supports various ordering specifications.

Parameters

  • spec - The ordering specification (see examples below)
  • opts - Additional options (typically empty for composable operations)

Ordering Specifications

  • :field - Order by field in ascending order
  • [field1, field2] - Order by multiple fields in ascending order
  • [asc: :field] - Explicitly specify ascending order
  • [desc: :field] - Order by field in descending order
  • [asc: :field1, desc: :field2] - Mixed ordering

Returns

Returns a relation struct that can be further composed or executed.

Examples

iex> # Simple ascending order
iex> ordered = MyApp.Users.order(:name) |> MyApp.Users.all()
iex> [first, second, third] = ordered
iex> first.name
"Bob Wilson"
iex> second.name
"Jane Smith"
iex> third.name
"John Doe"

iex> # Descending order by age
iex> by_age = MyApp.Users.order(desc: :age) |> MyApp.Users.all()
iex> [first, second, third] = by_age
iex> first.age
35
iex> second.age
30
iex> third.age
25

iex> # Chained with restrictions
iex> result = MyApp.Users.restrict(active: true) |> MyApp.Users.order(:name) |> MyApp.Users.all()
iex> length(result)
2
iex> hd(result).name
"Jane Smith"

order(other, spec, opts)

@spec order(queryable(), order_spec(), keyword()) :: relation()

Orders the given queryable by the specified criteria.

This is the two-argument version that takes an existing queryable (relation or query) and applies ordering to it.

Parameters

  • other - An existing queryable (relation struct or Ecto query)
  • spec - The ordering specification (see order/2 for details)
  • opts - Additional options (typically empty for composable operations)

Examples

# Apply ordering to existing relation
base_query = MyApp.Users.restrict(active: true)
ordered = MyApp.Users.order(base_query, :name)

# Chain multiple orderings (last one takes precedence)
sorted = Users
         |> MyApp.Users.order(:created_at)
         |> MyApp.Users.order(:name)  # This will be the final ordering

Returns

Returns a relation struct that can be further composed or executed.

preload(association, opts)

@spec preload(
  atom(),
  keyword()
) :: relation()
@spec preload(
  preload_spec(),
  keyword()
) :: relation()

preload(other, association, opts)

@spec preload(queryable(), atom(), keyword()) :: relation()
@spec preload(queryable(), preload_spec(), keyword()) :: relation()

Preloads associations in queries.

This function creates composable query operations that preload the specified associations when the query is executed. It supports multiple function signatures for different use cases.

Function Signatures

  • preload(association, opts) - Preload a single association
  • preload(associations, opts) - Preload multiple associations
  • preload(other, association, opts) - Preload single association from existing queryable
  • preload(other, associations, opts) - Preload multiple associations from existing queryable

Parameters

  • other - An existing queryable (relation struct or Ecto query)
  • association - A single association name as an atom
  • associations - List of association names or nested preload specification
  • opts - Additional options (typically empty for composable operations)

Preload Specifications

  • :assoc - Preload single association
  • [:assoc1, :assoc2] - Preload multiple associations
  • [assoc: :nested] - Preload nested associations
  • [assoc: [:nested1, :nested2]] - Preload multiple nested associations

Examples

# Preload single association
with_posts = MyApp.Users.preload(:posts)

# Preload multiple associations
with_assocs = MyApp.Users.preload([:posts, :profile])

# Nested preloads
nested = MyApp.Users.preload([posts: :comments])

# Complex nested preloads
complex = MyApp.Users.preload([posts: [:comments, :tags], :profile])

# Preload from existing query
base_query = MyApp.Users.restrict(active: true)
with_posts = MyApp.Users.preload(base_query, :posts)

# Chain with other operations
result = Users
         |> MyApp.Users.restrict(active: true)
         |> MyApp.Users.order(:name)
         |> MyApp.Users.preload([:posts, :profile])
         |> MyApp.Users.all()

Returns

Returns a relation struct that can be further composed or executed.

restrict(spec, opts)

@spec restrict(
  restrict_spec(),
  keyword()
) :: relation()
@spec restrict(
  queryable(),
  keyword()
) :: relation()

Restricts the query with the given conditions.

This function creates a composable query operation that adds WHERE conditions to filter records. It can be used standalone or chained with other operations.

Parameters

  • spec - A keyword list of field-value pairs to filter by
  • opts - Additional options (typically empty for composable operations)

Returns

Returns a relation struct that can be further composed or executed.

Examples

iex> # Create a restriction query
iex> active_users = MyApp.Users.restrict(active: true)
iex> users = MyApp.Users.all(active_users)
iex> length(users)
2
iex> Enum.all?(users, & &1.active)
true

iex> # Chain with other operations
iex> result = MyApp.Users.restrict(active: true) |> MyApp.Users.order(:name) |> MyApp.Users.all()
iex> length(result)
2
iex> hd(result).name
"Jane Smith"

iex> # Multiple conditions
iex> filtered = MyApp.Users.restrict(active: true, name: "John Doe") |> MyApp.Users.all()
iex> length(filtered)
1
iex> hd(filtered).name
"John Doe"

restrict(other, spec, opts)

Restricts the given queryable with the specified conditions.

This is the two-argument version that takes an existing queryable (relation or query) and applies additional restrictions to it.

Parameters

  • other - An existing queryable (relation struct or Ecto query)
  • spec - A keyword list of field-value pairs to filter by
  • opts - Additional options (typically empty for composable operations)

Examples

# Apply restriction to existing relation
base_query = MyApp.Users.order(:name)
active_users = MyApp.Users.restrict(base_query, active: true)

# Chain multiple restrictions
filtered = Users
           |> MyApp.Users.restrict(active: true)
           |> MyApp.Users.restrict(role: "admin")

Returns

Returns a relation struct that can be further composed or executed.

Query API

aggregate(aggregate, opts)

Calculates the given aggregate.

Delegates to Ecto.Repo.aggregate/3 or Ecto.Repo.aggregate/4. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

count = MyRelation.aggregate(:count)
avg_age = MyRelation.aggregate(:avg, :age)
max_id = MyRelation.aggregate(:max, :id, repo: AnotherRepo)

See Ecto.Repo.aggregate/3 and Ecto.Repo.aggregate/4 for more details.

aggregate(aggregate, field, opts)

all(opts \\ [])

@spec all(keyword()) :: [struct()]

Fetches all records from the relation.

This function retrieves all records from the database table associated with the relation. It can also execute a composable relation query built with functions like restrict/2 and order/2.

Parameters

  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration
  • :telemetry_event - Override telemetry event name

Returns

A list of record structs. Returns an empty list if no records are found.

Examples

iex> users = MyApp.Users.all()
iex> length(users)
3
iex> hd(users).name
"John Doe"
...>
iex> active_users = MyApp.Users.restrict(active: true)
...>    |> MyApp.Users.order(:name)
...>    |> MyApp.Users.all()
iex>
iex> length(active_users)
2
iex> hd(active_users).name
"Jane Smith"

Performance Considerations

Be cautious when calling all/1 on large tables without restrictions, as it will load all records into memory.

# Better: use restrictions to limit results
recent_users = Users
               |> MyApp.Users.restrict(inserted_at: {:>, days_ago(30)})
               |> MyApp.Users.all()

See Ecto.Repo.all/2 for more details on the underlying implementation.

all(relation, opts)

@spec all(struct(), keyword()) :: [struct()]

Fetches all records from a composable relation query.

This function head handles the case where a composable relation struct is passed as the first argument, allowing you to execute queries built with restrict/2, order/2, etc.

Parameters

  • relation - A composable relation struct built with query functions
  • opts - Additional options (optional, defaults to [])

Returns

A list of record structs matching the relation query.

Examples

# Build and execute a composable query
query = MyApp.Users.restrict(active: true)
users = MyApp.Users.all(query)

# Equivalent to:
users = Users
        |> MyApp.Users.restrict(active: true)
        |> MyApp.Users.all()

all_by(clauses, opts)

Fetches all records matching the given clauses.

Delegates to Ecto.Repo.all/2 with a where clause. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • clauses - Keyword list of field-value pairs to match
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

A list of record structs matching the given clauses. Returns an empty list if no records are found.

Examples

iex> users = MyApp.Users.all_by(active: true)
iex> length(users)
2
iex> Enum.all?(users, & &1.active)
true

iex> # Get by multiple clauses
iex> users = MyApp.Users.all_by(name: "John Doe", active: true)
iex> length(users)
1
iex> hd(users).name
"John Doe"

iex> # Returns empty list if no matches
iex> MyApp.Users.all_by(active: false, age: 100)
[]

See Ecto.Repo.all_by/2 for more details.

avg(field, opts \\ [])

Returns the average value for the given field.

This is a convenience function that delegates to aggregate/3 with :avg.

Parameters

  • field - The field to calculate the average for
  • opts - Additional options (optional, defaults to [])

Examples

avg_age = MyApp.Users.avg(:age)
avg_age = MyApp.Users.avg(:age, repo: AnotherRepo)

See aggregate/3 for more details.

avg(relation, field, opts)

Returns the average value for the given field from a composable relation query.

Parameters

  • relation - A composable relation struct built with query functions
  • field - The field to calculate the average for
  • opts - Additional options (automatically provided by delegate_to)

Examples

query = MyApp.Users.restrict(active: true)
avg_age = MyApp.Users.avg(query, :age)

checkout(fun, opts)

Checks out a connection for the duration of the function.

Delegates to Ecto.Repo.checkout/2. The :repo option is automatically set based on the repository configured in the use macro, but can be overridden.

Examples

result = MyRelation.checkout(fn ->
  # database operations with checked out connection
end)

See Ecto.Repo.checkout/2 for more details.

count(opts \\ [])

Returns the count of records.

Delegates to Ecto.Repo.aggregate/3. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

iex> MyApp.Users.count()
3

See Ecto.Repo.aggregate/3 for more details.

count(relation, opts)

@spec count(struct(), keyword()) :: non_neg_integer()

Returns the count of records from a composable relation query.

This function head handles the case where a composable relation struct is passed as the first argument, allowing you to count records from queries built with restrict/2, order/2, etc.

Parameters

  • relation - A composable relation struct built with query functions
  • opts - Additional options (automatically provided by delegate_to)

Returns

An integer representing the count of records matching the relation query.

Examples

# Build and execute a composable query
query = MyApp.Users.restrict(active: true)
count = MyApp.Users.count(query)

# Equivalent to:
count = Users
        |> MyApp.Users.restrict(active: true)
        |> MyApp.Users.count()

delete_all(opts)

Deletes all entries matching the given query.

Delegates to Ecto.Repo.delete_all/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

{count, _} = MyRelation.delete_all()
{count, _} = MyRelation.delete_all(repo: AnotherRepo)

See Ecto.Repo.delete_all/2 for more details.

exists?(opts)

Checks if any entry matches the given query.

Delegates to Ecto.Repo.exists?/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

  • true if any records exist
  • false if no records exist

Examples

iex> MyApp.Users.exists?()
true

iex> # Check if any active users exist (using basic exists)
iex> MyApp.Users.exists?()
true

See Ecto.Repo.exists?/2 for more details.

first(opts \\ [])

Returns the first record.

Delegates to Ecto.Repo.one/2 with Ecto.Query.first/1. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

The first record struct, or nil if no records exist.

Examples

iex> user = MyApp.Users.first()
iex> user.name
"John Doe"
iex> user.id
1

See Ecto.Repo.one/2 and Ecto.Query.first/1 for more details.

first(relation, opts)

@spec first(struct(), keyword()) :: struct() | nil

Returns the first record from a composable relation query.

This function head handles the case where a composable relation struct is passed as the first argument, allowing you to get the first record from queries built with restrict/2, order/2, etc.

Parameters

  • relation - A composable relation struct built with query functions
  • opts - Additional options (automatically provided by delegate_to)

Returns

The first record struct matching the relation query, or nil if no records are found.

Examples

# Build and execute a composable query
query = MyApp.Users.restrict(active: true) |> MyApp.Users.order(:name)
user = MyApp.Users.first(query)

# Equivalent to:
user = Users
       |> MyApp.Users.restrict(active: true)
       |> MyApp.Users.order(:name)
       |> MyApp.Users.first()

get(id, opts \\ [])

@spec get(
  term(),
  keyword()
) :: struct() | nil

Fetches a single record by its primary key.

This function retrieves a single record from the database using the primary key value. It returns the record if found, or nil if no record exists with the given primary key.

Parameters

  • id - The primary key value to search for
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration
  • :telemetry_event - Override telemetry event name

Returns

  • The record struct if found
  • nil if no record exists with the given primary key

Examples

iex> user = MyApp.Users.get(1)
iex> user.name
"John Doe"
iex> user.email
"john@example.com"
...>
iex> MyApp.Users.get(999)
nil

See Ecto.Repo.get/3 for more details on the underlying implementation.

get!(id, opts \\ [])

@spec get!(
  term(),
  keyword()
) :: struct()

Fetches a single record by its primary key, raising if not found.

This function retrieves a single record from the database using the primary key value. Unlike get/2, this function raises an Ecto.NoResultsError if no record is found with the given primary key.

Parameters

  • id - The primary key value to search for
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration
  • :telemetry_event - Override telemetry event name

Returns

  • The record struct if found
  • Raises Ecto.NoResultsError if no record exists with the given primary key

Examples

# Get user by ID
user = MyApp.Users.get!(1)
# => %MyApp.Users.Struct{id: 1, name: "John", email: "john@example.com"}

# Raises if not found
user = MyApp.Users.get!(999)
# => ** (Ecto.NoResultsError) expected at least one result but got none

# Override repository
user = MyApp.Users.get!(1, repo: AnotherRepo)

# With timeout option
user = MyApp.Users.get!(1, timeout: 5000)

Error Handling

try do
  user = MyApp.Users.get!(user_id)
  process_user(user)
rescue
  Ecto.NoResultsError ->
    {:error, :not_found}
end

See Ecto.Repo.get!/3 for more details on the underlying implementation.

get_by(clauses, opts)

Gets a single record by the given clauses.

Delegates to Ecto.Repo.get_by/3. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • clauses - Keyword list of field-value pairs to match
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

  • The record struct if found
  • nil if no record matches the given clauses

Examples

iex> user = MyApp.Users.get_by(email: "jane@example.com")
iex> user.name
"Jane Smith"
iex> user.email
"jane@example.com"

iex> # Get by multiple clauses
iex> user = MyApp.Users.get_by(name: "John Doe", active: true)
iex> user.name
"John Doe"
iex> user.active
true

iex> # Returns nil if not found
iex> MyApp.Users.get_by(email: "nonexistent@example.com")
nil

See Ecto.Repo.get_by/3 for more details.

get_by!(clauses, opts)

Gets a single record by the given clauses, raises if not found.

Delegates to Ecto.Repo.get_by!/3. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • clauses - Keyword list of field-value pairs to match
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

Examples

iex> user = MyApp.Users.get_by!(email: "jane@example.com")
iex> user.name
"Jane Smith"
iex> user.email
"jane@example.com"

iex> # Get by multiple clauses
iex> user = MyApp.Users.get_by!(name: "John Doe", active: true)
iex> user.name
"John Doe"
iex> user.active
true

iex> # Raises if not found
iex> try do
...>   MyApp.Users.get_by!(email: "nonexistent@example.com")
...> rescue
...>   Ecto.NoResultsError -> :not_found
...> end
:not_found

See Ecto.Repo.get_by!/3 for more details.

in_transaction?(opts)

Returns true if the current process is inside a transaction.

Delegates to Ecto.Repo.in_transaction?/0. The :repo option is automatically set based on the repository configured in the use macro, but can be overridden.

Examples

in_tx = MyRelation.in_transaction?()

See Ecto.Repo.in_transaction?/0 for more details.

last(opts \\ [])

Returns the last record.

Delegates to Ecto.Repo.one/2 with Ecto.Query.last/1. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

The last record struct, or nil if no records exist.

Examples

iex> user = MyApp.Users.last()
iex> user.name
"Bob Wilson"
iex> user.id
3

See Ecto.Repo.one/2 and Ecto.Query.last/1 for more details.

last(relation, opts)

@spec last(struct(), keyword()) :: struct() | nil

Returns the last record from a composable relation query.

This function head handles the case where a composable relation struct is passed as the first argument, allowing you to get the last record from queries built with restrict/2, order/2, etc.

Parameters

  • relation - A composable relation struct built with query functions
  • opts - Additional options (automatically provided by delegate_to)

Returns

The last record struct matching the relation query, or nil if no records are found.

Examples

# Build and execute a composable query
query = MyApp.Users.restrict(active: true) |> MyApp.Users.order(:name)
user = MyApp.Users.last(query)

# Equivalent to:
user = Users
       |> MyApp.Users.restrict(active: true)
       |> MyApp.Users.order(:name)
       |> MyApp.Users.last()

max(field, opts \\ [])

Returns the maximum value for the given field.

This is a convenience function that delegates to aggregate/3 with :max.

Parameters

  • field - The field to calculate the maximum value for
  • opts - Additional options (optional, defaults to [])

Examples

max_age = MyApp.Users.max(:age)
max_age = MyApp.Users.max(:age, repo: AnotherRepo)

See aggregate/3 for more details.

max(relation, field, opts)

Returns the maximum value for the given field from a composable relation query.

Parameters

  • relation - A composable relation struct built with query functions
  • field - The field to calculate the maximum value for
  • opts - Additional options (automatically provided by delegate_to)

Examples

query = MyApp.Users.restrict(active: true)
max_age = MyApp.Users.max(query, :age)

min(field, opts \\ [])

Returns the minimum value for the given field.

This is a convenience function that delegates to aggregate/3 with :min.

Parameters

  • field - The field to calculate the minimum value for
  • opts - Additional options (optional, defaults to [])

Examples

min_age = MyApp.Users.min(:age)
min_age = MyApp.Users.min(:age, repo: AnotherRepo)

See aggregate/3 for more details.

min(relation, field, opts)

Returns the minimum value for the given field from a composable relation query.

Parameters

  • relation - A composable relation struct built with query functions
  • field - The field to calculate the minimum value for
  • opts - Additional options (automatically provided by delegate_to)

Examples

query = MyApp.Users.restrict(active: true)
min_age = MyApp.Users.min(query, :age)

one(opts \\ [])

Fetches a single result from the query.

Delegates to Ecto.Repo.one/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

  • The single record struct if exactly one record is found
  • nil if no records are found
  • Raises Ecto.MultipleResultsError if more than one record is found

Examples

iex> # Get a single user (when only one exists matching criteria)
iex> user = MyApp.Users.restrict(name: "John Doe") |> MyApp.Users.one()
iex> user.name
"John Doe"

iex> # Returns nil when no records match
iex> MyApp.Users.restrict(name: "Nonexistent") |> MyApp.Users.one()
nil

See Ecto.Repo.one/2 for more details.

one(relation, opts)

@spec one(struct(), keyword()) :: struct() | nil

Fetches a single result from a composable relation query.

This function head handles the case where a composable relation struct is passed as the first argument, allowing you to execute queries built with restrict/2, order/2, etc.

Parameters

  • relation - A composable relation struct built with query functions
  • opts - Additional options (automatically provided by delegate_to)

Returns

A single record struct matching the relation query, or nil if no record is found.

Examples

# Build and execute a composable query
query = MyApp.Users.restrict(active: true)
user = MyApp.Users.one(query)

# Equivalent to:
user = Users
       |> MyApp.Users.restrict(active: true)
       |> MyApp.Users.one()

one!(opts \\ [])

Fetches a single result from the query, raises if not found or more than one.

Delegates to Ecto.Repo.one!/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

user = MyRelation.one!(query)
user = MyRelation.one!(query, repo: AnotherRepo)

See Ecto.Repo.one!/2 for more details.

one!(relation, opts)

@spec one!(struct(), keyword()) :: struct()

Fetches a single result from a composable relation query, raises if not found or more than one.

This function head handles the case where a composable relation struct is passed as the first argument, allowing you to execute queries built with restrict/2, order/2, etc.

Parameters

  • relation - A composable relation struct built with query functions
  • opts - Additional options (automatically provided by delegate_to)

Returns

A single record struct matching the relation query. Raises Ecto.NoResultsError if no record is found, or Ecto.MultipleResultsError if more than one record is found.

Examples

# Build and execute a composable query
query = MyApp.Users.restrict(active: true)
user = MyApp.Users.one!(query)

# Equivalent to:
user = Users
       |> MyApp.Users.restrict(active: true)
       |> MyApp.Users.one!()

stream(opts)

Returns a lazy enumerable that emits all entries from the data store.

Delegates to Ecto.Repo.stream/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

stream = MyRelation.stream()
stream = MyRelation.stream(repo: AnotherRepo)

See Ecto.Repo.stream/2 for more details.

sum(field, opts \\ [])

Returns the sum of values for the given field.

This is a convenience function that delegates to aggregate/3 with :sum.

Parameters

  • field - The field to calculate the sum for
  • opts - Additional options (optional, defaults to [])

Examples

total_age = MyApp.Users.sum(:age)
total_age = MyApp.Users.sum(:age, repo: AnotherRepo)

See aggregate/3 for more details.

sum(relation, field, opts)

Returns the sum of values for the given field from a composable relation query.

Parameters

  • relation - A composable relation struct built with query functions
  • field - The field to calculate the sum for
  • opts - Additional options (automatically provided by delegate_to)

Examples

query = MyApp.Users.restrict(active: true)
total_age = MyApp.Users.sum(query, :age)

transaction(fun_or_multi, opts)

Runs the given function or Ecto.Multi inside a transaction.

Delegates to Ecto.Repo.transaction/2. The :repo option is automatically set based on the repository configured in the use macro, but can be overridden.

Examples

{:ok, result} = MyRelation.transaction(fn ->
  # database operations
end)

{:ok, changes} = MyRelation.transaction(multi, repo: AnotherRepo)

See Ecto.Repo.transaction/2 for more details.

update_all(updates, opts)

Updates all entries matching the given query with the given values.

Delegates to Ecto.Repo.update_all/3. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

{count, _} = MyRelation.update_all(set: [active: false])
{count, _} = MyRelation.update_all([set: [active: false]], repo: AnotherRepo)

See Ecto.Repo.update_all/3 for more details.