2015-11-27 13 views
12

Nel mio Tag codice modelloCome utilizzare il modulo Repo nel mio file di modello

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 

Sopra codice ha causato un errore di seguito.

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

Posso correggere l'errore?

Il modello Tag è modello di tag nidificato.

Il tag può contenere il tag principale.


Il codice finale è di seguito. Questo funziona bene.

Nel modello

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 

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

risposta

17

Non è possibile utilizzare la variabile Repo in quanto non è disponibile in questo modulo. Avrete bisogno di alias è:

alias MyApp.Repo 

Nei controllori questo viene manipolato per voi in web.ex che viene chiamato nel vostro modulo con:

use MyApp.Web, :controller 

Tuttavia, ho fortemente suggeriscono di evitare l'uso Repo nel tuo modello. I tuoi modelli sono pensati per essere puri, questo significa che non dovrebbero avere effetti collaterali. Chiamare una funzione nel modello dovrebbe sempre avere lo stesso risultato per un particolare input (idempotence).

In questo esempio si potrebbe modificare l'implementazione della funzione da:

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 

È possibile chiamare Repo.all nel controller e passare i tag attraverso la funzione.

Se si dispone di un comportamento più complesso, prendere in considerazione la creazione di un modulo TagService che utilizza la funzione così come chiamare il Repo.all

+0

Grazie per la risposta dettagliata! Proverò a scrivere in 'tag_controller.ex' la logica di validazione. Perché, non ho altra logica finora per il modello Tag. – 2YY

+0

Oops, ho fatto un errore ... proverò a scrivere in 'tag.ex' la pura logica come funzione e chiamare la funzione dal controller. Ho capito il punto. 'changeset = Tag.changeset (% Tag {}, tag_params) |> Tag.add_error_when_not_exists_tag_id (tag_params)' – 2YY

Problemi correlati