Как использовать модуль Repo в моем файле модели
В моем коде модели тега
schema "tags" do
field :name, :string
field :parent, :integer # parent tag id
timestamps
end
def add_error_when_not_exists_tag_id(changeset, params) do
tags = Repo.all(Tag)
is_exists_tag_id = Enum.reduce(tags, fn(x, acc) -> acc || (x.id === params.parent) end)
if is_exists_tag_id, do: changeset, else: add_error(changeset, :parent, "not exists parent!")
end
Выше код вызвал ошибку ниже.
(UndefinedFunctionError) undefined function: Repo.all/1 (module Repo is not available)
Могу ли я исправить ошибку?
Модель тега - это модель вложенного тега.
Тег может иметь родительский тег.
Окончательный код ниже. Это нормально работает.
В модели
def add_error_when_not_exists_tag_id(changeset, params, tags) do
is_exists_tag_id = Enum.reduce(tags, false, fn(x, acc) -> acc || (Integer.to_string(x.id) === params["parent"]) end)
if is_exists_tag_id, do: changeset, else: add_error(changeset, :parent, "The tag is not exists.")
end
В контроллере
def create(conn, %{"tag" => tag_params}) do
changeset = Tag.changeset(%Tag{}, tag_params)
|> Tag.add_error_when_not_exists_tag_id(tag_params, Repo.all(Tag))
//
// ...
1 ответ
Вы не можете использовать Repo
переменная, поскольку она не доступна в этом модуле. Вам нужно будет псевдоним это:
alias MyApp.Repo
В контроллерах это обрабатывается для вас в web.ex
который вызывается в вашем модуле с:
use MyApp.Web, :controller
Тем не менее, я настоятельно рекомендую вам избегать использования Repo
в твоей модели. Ваши модели должны быть чистыми, это означает, что они не должны иметь побочных эффектов. Вызов функции в вашей модели должен всегда иметь один и тот же выход для определенного входа (идемпотентность).
В этом примере вы можете изменить реализацию функции на:
def add_error_when_not_exists_tag_id(changeset, params, tags) do
is_exists_tag_id = Enum.reduce(tags, fn(x, acc) -> acc || (x.id === params.parent) end)
if is_exists_tag_id, do: changeset, else: add_error(changeset, :parent, "not exists parent!")
end
Ты можешь позвонить Repo.all
в вашем контроллере и передать теги через функцию.
Если у вас более сложное поведение, подумайте о создании TagService
модуль, который использует функцию, а также вызывает Repo.all