Current section
Files
Jump to
Current section
Files
lib/translecto/schema/translation.ex
defmodule Translecto.Schema.Translation do
import Ecto.Schema
@moduledoc """
Sets up a translation schema.
This module coincides with the migration function `Translecto.Migration.translation/1`.
To correctly use this module a schema should call `use Translecto.Schema.Translation`,
overriding the default primary_key behaviour if needed and then adding the `translation/1`
macro to the schema.
"""
defmacro __using__(options) do
pkey = if Keyword.get(options, :primary_key, true) do
quote do: @primary_key { :translate_id, :id, autogenerate: true }
end
quote do
import Translecto.Schema.Translation
import Translecto.Changeset
unquote(pkey)
end
end
@doc """
Setup the schema as a translation.
It refers to the `:translecto` config's `:locale` field to get the default type information.
Alternativaly this type information may be passed in through the options argument under the
`:locale` key. The following variants are:
\# Declares a belong_to for the :locale field, referencing the model module. Optionally
\# passing in any options specified.
{ :model, module }
{ :model, module, options }
\# Declares a field of the specified type for the :locale_id field. Optionally passing in
\# any options specified.
{ :type, type }
{ :type, type, options }
An example translation schema:
defmodule Ingredient.Translation do
use Translecto.Schema.Translation
schema "ingredient_translations" do
translation
field :term, :string
end
def changeset(struct, params \\\\ %{}) do
struct
|> translation_changeset(params)
|> cast(params, [:term])
|> validate_required([:term])
end
end
defmodule Item.Translation do
use Translecto.Schema.Translation
schema "item_translations" do
translation locale: { :type, :string }
field :name, :string
field :description, :string
end
def changeset(struct, params \\\\ %{}) do
struct
|> translation_changeset(params)
|> cast(params, [:name, :description])
|> validate_required([:name, :description])
end
end
"""
@spec translation(keyword()) :: Macro.t
defmacro translation(opts \\ []) do
case if(opts[:locale], do: opts[:locale], else: Application.fetch_env!(:translecto, :locale)[:schema]) do
{ :model, model } -> quote do: belongs_to :locale, unquote(model)
{ :model, model, options } -> quote do: belongs_to :locale, unquote(model), unquote(options)
{ :type, type } -> quote do: field :locale_id, unquote(type)
{ :type, type, options } -> quote do: field :locale_id, unquote(type), unquote(options)
end
end
end