View Source Utilx.EctoUtils (Utilx v0.6.2)
A utility module for handling Ecto queries, with functions to perform common tasks like applying a range filter, and executing a series of query operations in a pipeline. This module includes Ecto changeset validation functions as well.
Summary
Functions
Applies a series of operations to an Ecto query.
Filters a query to only include rows where the specified column's value is within a provided range.
Validates the structure of a URL field in an Ecto changeset. It does not make it required field.
Functions
@spec apply_options(Ecto.Queryable.t(), Keyword.t()) :: Ecto.Queryable.t()
Applies a series of operations to an Ecto query.
Parameters
query
: The Ecto query to which operations should be applied.opts
: A list of operations to apply. Each operation is a tuple where the first element is the operation name and the second element is the value to use for that operation.
The following operations are supported:
{:where, filters}
: Adds awhere
clause to the query.{:select, fields}
: Adds aselect
clause to the query.{:order_by, criteria}
: Adds anorder_by
clause to the query.{:limit, criteria}
: Adds alimit
clause to the query.{:preload, preload}
: Adds apreload
clause to the query.
Invalid options are ignored from query result.
Examples
iex> query = from(u in "users")
iex> EctoUtils.apply_options(query, where: [age: 18], select: [:id, :email])
#Ecto.Query<from u0 in "users", where: u0.age == ^18, select: map(u0, [:id, :email])>
iex> query = from(u in "users")
iex> filters = [
...> {:where, [age: 18]},
...> {:order_by, [desc: :age]},
...> {:select, [:id, :email]},
...> {:limit, 10},
...> {:preload, :posts},
...>]
iex> EctoUtils.apply_options(query, filters)
#Ecto.Query<from u0 in "users", where: u0.age == ^18, order_by: [desc: u0.age], limit: ^10, select: map(u0, [:id, :email]), preload: [:posts]>
Filters a query to only include rows where the specified column's value is within a provided range.
Parameters
query
: The Ecto query to filter.column
: The column on which to apply the range filter.min..max
: The range of values to filter on.
Examples
iex> query = from(u in "users", select: u.age)
iex> EctoUtils.in_range(query, :age, 18..30)
#Ecto.Query<from u0 in "users", where: u0.age >= ^18 and u0.age <= ^30, select: u0.age>
Validates the structure of a URL field in an Ecto changeset. It does not make it required field.
If the field
in the changeset
is a URL, this function ensures that it has a scheme (defaulting to "https://" if
none is present), and then checks the URL's structure against a regular expression.
If the URL's structure is invalid, the error_message
is attached to the field
in the changeset
's errors.
Parameters
changeset
: The Ecto changeset containing the URL to validate.field
: The key (atom) for the field in the changeset containing the URL.error_message
: The error message to attach to thefield
in thechangeset
if the URL is invalid.
Examples
iex> types = %{url: :string}
iex> params = %{url: "https://www.example.com/"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> EctoUtils.validate_url(:url, "is not a valid url")
#Ecto.Changeset<action: nil, changes: %{url: "https://www.example.com/"}, errors: [], data: %{}, valid?: true>
iex> types = %{url: :string}
iex> params = %{url: "www.example.com/"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> EctoUtils.validate_url(:url, "is not a valid url")
#Ecto.Changeset<action: nil, changes: %{url: "https://www.example.com/"}, errors: [], data: %{}, valid?: true>
iex> types = %{url: :string}
iex> params = %{url: nil}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> EctoUtils.validate_url(:url, "is not a valid url")
#Ecto.Changeset<action: nil, changes: %{}, errors: [], data: %{}, valid?: true>
iex> types = %{url: :string}
iex> params = %{url: "some@invalid_url"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> EctoUtils.validate_url(:url, "is not a valid url")
#Ecto.Changeset<action: nil, changes: %{url: "https://some@invalid_url"}, errors: [url: {"is not a valid url", [validation: :format]}], data: %{}, valid?: false>
iex> types = %{url: :string}
iex> params = %{url: "Just some random text"}
iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
...> |> EctoUtils.validate_url(:url, "is not a valid url")
#Ecto.Changeset<action: nil, changes: %{url: "https://Just some random text"}, errors: [url: {"is not a valid url", [validation: :format]}], data: %{}, valid?: false>