calcinator v5.0.0 Calcinator.Resources.Sort View Source
Sort in Calcinator.Resources.query_options
Link to this section Summary
Types
Keyword list of association path used to Ecto preloading
Used to convert includes used by JSONAPI to the corresponding association in Ecto
The direction to sort. Default to :ascending
per the JSONAPI spec. Can be :descending
when the dot-separated
attribute path is prefixed with -
Name of a field in an Ecto.Schema.t
:associations_by_include
- maps theAlembic.Fetch.Includes.t
to Keyword.t of associations.:ecto_schema_module
- primary Ecto.Schema module for checking if attribute is an existent field after applying associations
Used to convert associations used in Ecto to JSONAPI includes
:assocation
- Keyword list of nested associations.nil
when the:field
is direction on the primary data.:direction
- the direction to sort:field
:field
- name of the field to sort
Functions
Maps Alembic.Fetch.Sort.t
attribute
to t
field
and Alembic.Fetch.Sort.t
relationships
to
t
associations
Maps t
field
to Alembic.Fetch.Sort.t
attribute
and t
associations
to Alembic.Fetch.Sort.t
relationships
Link to this section Types
Keyword list of association path used to Ecto preloading
associations_by_include() :: %{optional(Alembic.Fetch.Includes.t) => association}
Used to convert includes used by JSONAPI to the corresponding association in Ecto.
This map does not need to be a simple conversion of the nested map of strings Alembic.Fetch.Includes.t
to
the Keyword.t
of associations
, but can include completely different names or associations that the JSONAPI doesn’t
even expose, so that deprecated relationships can be mapped to newer associations.
The direction to sort. Default to :ascending
per the JSONAPI spec. Can be :descending
when the dot-separated
attribute path is prefixed with -
.
Name of a field in an Ecto.Schema.t
from_alembic_fetch_sort_options() :: %{associations_by_include: associations_by_include, ecto_schema_module: module}
:associations_by_include
- maps theAlembic.Fetch.Includes.t
to Keyword.t of associations.:ecto_schema_module
- primary Ecto.Schema module for checking if attribute is an existent field after applying associations.
include_by_associations() :: %{optional(association) => Alembic.Fetch.Includes.t}
Used to convert associations used in Ecto to JSONAPI includes.
This map need not be the inverse of associations_by_include
if the JSONAPI incoming relationships are no the same
as the outgoing relationships.
t() :: %Calcinator.Resources.Sort{association: nil | association, direction: direction, field: field_name}
:assocation
- Keyword list of nested associations.nil
when the:field
is direction on the primary data.:direction
- the direction to sort:field
:field
- name of the field to sort
Link to this section Functions
from_alembic_fetch_sort(Alembic.Fetch.Sort.t, from_alembic_fetch_sort_options) :: {:ok, t} | {:error, Alembic.Document.t}
Maps Alembic.Fetch.Sort.t
attribute
to t
field
and Alembic.Fetch.Sort.t
relationships
to
t
associations
.
When there are no relationships
, there are no assocations
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "inserted-at"
...> },
...> %{
...> associations_by_include: %{},
...> ecto_schema_module: Calcinator.Resources.TestPost
...> }
...> )
{
:ok,
%Calcinator.Resources.Sort{field: :inserted_at}
}
When there is relationship
it is converted to association using :associations_by_include
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "inserted-at",
...> relationship: "posts"
...> },
...> %{
...> associations_by_include: %{"posts" => :posts},
...> ecto_schema_module: Calcinator.Resources.TestAuthor
...> }
...> )
{
:ok,
%Calcinator.Resources.Sort{
association: :posts,
direction: :ascending,
field: :inserted_at
}
}
The relationship can also be nested and it will be converted using :associations_by_include
too
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "inserted-at",
...> relationship: %{
...> "posts" => "comments"
...> }
...> },
...> %{
...> associations_by_include: %{
...> %{
...> "posts" => "comments"
...> } => [posts: :comments]
...> },
...> ecto_schema_module: Calcinator.Resources.TestAuthor
...> }
...> )
{
:ok,
%Calcinator.Resources.Sort{
association: [posts: :comments],
direction: :ascending,
field: :inserted_at
}
}
Errors
If the Alembic.Fetch.Sort.t
relationship
is not in :associations_by_include
, then an error is returned
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "inserted-at",
...> relationship: "author"
...> },
...> %{
...> associations_by_include: %{},
...> ecto_schema_module: Calcinator.Resources.TestPost
...> }
...> )
{
:error,
%Alembic.Document{
errors: [
%Alembic.Error{
detail: "`author` is an unknown relationship path",
meta: %{
"relationship_path" => "author"
},
source: %Alembic.Source{
parameter: "include"
},
title: "Unknown relationship path"
}
]
}
}
If the Alembic.Fetch.Sort.t
attribute
is not on :ecto_schema_module
when there is no relationship
, then an
error is returned with only the attribute
in it
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "likes",
...> relationship: nil
...> },
...> %{
...> associations_by_include: %{},
...> ecto_schema_module: Calcinator.Resources.TestPost
...> }
...> )
{
:error,
%Alembic.Document{
errors: [
%Alembic.Error{
detail: "Does not have `likes` attribute",
meta: %{
"attribute" => "likes"
},
source: %Alembic.Source{
parameter: "sort"
},
title: "Unknown attribute"
}
]
}
}
If the Alembic.Fetch.Sort.t
attribute
is not on the associated Ecto.Schema
module, than an error is returned
with both the relationship
and attribute
in it.
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "title",
...> relationship: "author"
...> },
...> %{
...> associations_by_include: %{
...> "author" => :author
...> },
...> ecto_schema_module: Calcinator.Resources.TestPost
...> }
...> )
{
:error,
%Alembic.Document{
errors: [
%Alembic.Error{
detail: "`author` does not have a `title` attribute",
meta: %{
"attribute" => "title",
"relationship_path" => "author"
},
source: %Alembic.Source{
parameter: "sort"
},
title: "Unknown attribute"
}
]
}
}
If the relationship is far, then the whole relationship is shown in the error
iex> Calcinator.Resources.Sort.from_alembic_fetch_sort(
...> %Alembic.Fetch.Sort{
...> attribute: "likes",
...> relationship: %{
...> "posts" => "comments"
...> }
...> },
...> %{
...> associations_by_include: %{
...> %{
...> "posts" => "comments"
...> } => [posts: :comments]
...> },
...> ecto_schema_module: Calcinator.Resources.TestAuthor
...> }
...> )
{
:error,
%Alembic.Document{
errors: [
%Alembic.Error{
detail: "`posts.comments` does not have a `likes` attribute",
meta: %{
"attribute" => "likes",
"relationship_path" => "posts.comments"
},
source: %Alembic.Source{
parameter: "sort"
},
title: "Unknown attribute"
}
]
}
}
to_alembic_fetch_sort(t, Calcinator.Resources.t) :: {:ok, Alembic.Fetch.Sort.t} | {:error, Alembic.Document.t}
Maps t
field
to Alembic.Fetch.Sort.t
attribute
and t
associations
to Alembic.Fetch.Sort.t
relationships
.