2015-11-27 6 views
12

In meinem Tag ModellcodeWie Repo-Modul in meiner Modelldatei

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 

Above-Code verwenden, um einen Fehler unten verursacht.

(UndefinedFunctionError) undefined function: Repo.all/1 (module Repo is not available) 

Kann ich den Fehler beheben? Das Tag-Modell ist verschachtelt Tag-Modell.

Tag-Dose hat Eltern-Tag.


Endgültiger Code ist unten. Das ist gut.

Im Modell

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 

In Controller

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)) 
    // 
    // ... 

Antwort

17

Sie können nicht die Repo Variable verwenden, da es in diesem Modul nicht verfügbar ist. Sie müssen es an Alias:

alias MyApp.Repo 

In Controller das für Sie in web.ex behandelt wird, die in Ihrem Modul mit aufgerufen wird: Jedoch

use MyApp.Web, :controller 

, ich stark vorschlagen, dass Sie vermeiden Repo mit in deinem Modell. Ihre Modelle sollen rein sein, das heißt, sie sollten keine Nebenwirkungen haben. Das Aufrufen einer Funktion in Ihrem Modell sollte immer die gleiche Ausgabe für eine bestimmte Eingabe haben (Idempotenz).

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 

Sie können Repo.all in Ihrem Controller aufrufen und die Tags durch an die Funktion übergeben:

In diesem Beispiel könnten Sie die Implementierung der Funktion ändern.

Wenn Sie ein komplexeres Verhalten haben, sollten Sie ein TagService Modul zu schaffen, die die Funktion auch verwendet als die anruf Repo.all

+0

Danke für die ausführliche Antwort! Ich werde versuchen, in "tag_controller.ex" die Validierungslogik zu schreiben. Weil ich bisher keine andere Logik für das Tag-Modell habe. – 2YY

+0

Hoppla, ich habe einen Fehler gemacht ... Ich werde versuchen, in 'tag.ex' die reine Logik als Funktion zu schreiben und die Funktion vom Controller aus aufzurufen. Ich verstehe. 'changeset = Tag.ändern (% Tag {}, tag_params) |> Tag.add_error_when_not_exists_tag_id (tag_params)' – 2YY