Current section

Files

Jump to
ex_teal lib ex_teal fields belongs_to.ex
Raw

lib/ex_teal/fields/belongs_to.ex

defmodule ExTeal.Fields.BelongsTo do
@moduledoc """
The `BelongsTo` field corresponds to a `belongs_to` ecto relationship. For example,
let's assume a `Post` schema `belongs_to` a `User` schema. We may add the relationship
to our `Post` ExTeal resource like so:
alias ExTeal.Fields.BelongsTo
BelongsTo.make(:user)
"""
use ExTeal.Field
alias ExTeal.Field
def component, do: "belongs-to"
@impl true
def filterable_as, do: ExTeal.FieldFilter.BelongsTo
@impl true
def make(relationship_name, module, label \\ nil) do
__MODULE__
|> Field.struct_from_field(relationship_name, label)
|> Map.put(:relationship, module)
end
@impl true
def value_for(field, model, _type) do
schema = Map.get(model, field.field)
case ExTeal.resource_for_model(field.relationship) do
{:ok, resource} ->
resource.title_for_schema(schema)
{:error, :not_found} ->
nil
end
end
@impl true
def apply_options_for(field, model, _conn, _type) do
id =
case Map.get(model, field.field) do
nil -> nil
module -> Map.get(module, :id)
end
case ExTeal.resource_for_model(field.relationship) do
{:ok, resource} ->
rel = model.__struct__.__schema__(:association, field.field)
opts =
Map.merge(field.options, %{
belongs_to_key: rel.owner_key,
belongs_to_relationship: resource.uri(),
belongs_to_id: id
})
Map.put(field, :options, opts)
{:error, _} ->
field
end
end
@doc """
Mark a Belongs To Field as searchable, allowing the UX to
search the related resource for matches in the create and update forms
"""
@spec searchable(Field.t()) :: Field.t()
def searchable(field) do
IO.warn("searchable/1 is deprecated. BelongsTo fields are always searchable")
field
end
end