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.tto 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.nilwhen the:fieldis 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.tto 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.nilwhen the:fieldis 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.