defmodule EctoJuno.Helpers.SortingParams do
@moduledoc """
Validator module for sorting parameters
"""
use Ecto.Schema
import Ecto.Changeset
alias EctoJuno.Helpers.SortingHelpers, as: Helpers
@default_sort_by Application.compile_env(:ecto_juno, :sort_by, :inserted_at)
@default_sort_direction Application.compile_env(:ecto_juno, :sort_direction, :asc)
@primary_key false
embedded_schema do
field :sort_by, :string, default: @default_sort_by, skip_default_validation: true
field :sort_direction, :string,
default: @default_sort_direction,
skip_default_validation: true
end
@doc """
Validation function. Relies on `Ecto.Changeset`. In the end invokes `apply_action!/2`
"""
@spec changeset!(map(), atom() | list()) :: map()
def changeset!(attrs, schema_or_list) do
%__MODULE__{}
|> cast(attrs, [:sort_by, :sort_direction])
|> atomize_sort_by(schema_or_list)
|> atomize_sort_direction()
|> validate_required([:sort_by, :sort_direction])
|> apply_action!(:insert)
end
defp atomize_sort_by(%{changes: %{sort_by: sort_by}} = changeset, schema_or_list)
when is_binary(sort_by) do
field =
sort_by
|> Helpers.map_string_field_to_atom(schema_or_list)
|> traverse_nil_value(@default_sort_by)
put_change(changeset, :sort_by, field)
end
defp atomize_sort_by(changeset, _schema_or_list),
do: changeset
defp atomize_sort_direction(%{changes: %{sort_direction: direction}} = changeset)
when is_binary(direction) do
sort_direction =
direction
|> Helpers.map_string_field_to_atom([:desc, :asc])
|> traverse_nil_value(@default_sort_direction)
put_change(changeset, :sort_direction, sort_direction)
end
defp atomize_sort_direction(changeset),
do: changeset
defp traverse_nil_value(nil, default), do: default
defp traverse_nil_value(field, _default), do: field
end