2015-04-27 20 views
8

Phoenix Framework utilizza qualsiasi tipo di filtro di callback come quelli trovati in Rails? So che è possibile convalidare i changeset, ma sto cercando modi per implementare azioni come before_create, before_save e after_commit.Callback di Phoenix Framework

risposta

13

Ecto fa: https://hexdocs.pm/ecto/#!Ecto.Model.Callbacks.html

Sono sightly diverse da quelle Rails: essi ricevono e devono tornare di modifiche e devono essere utilizzati per la coerenza dei dati (non utilizzarli per inviare e-mail e cosa no).

+0

Il la pagina dice che "Attenzione: le call call Ecto sono deprecate". Questo metodo probabilmente non è più raccomandato – coderVishal

+0

Sì e sono stati completamente rimossi da Ecto 2.0. Ecco il post sul blog che spiega alcune decisioni: http://blog.plataformatec.com.br/2015/12/ecto-v1-1-released-and-ecto-v2-0-plans/ –

+1

Ecco un altro punto di vista (se vieni da Rails): http://cloudless.pl/articles/ 11-modello-callbacks-in-phoenix-ecto-and-rail –

11

Da Ecto 2.0, i callback sono stati completamente rimossi.

Quindi, come gestire i callback ora ?. Ecco due modi

Per i callback before_ è possibile utilizzare lo stesso Changeset. Uno dei motivi per cui i callback sono stati rimossi perché molti sviluppatori facevano affidamento sui callback in molti casi in cui i changeset sarebbero stati sufficienti. Quindi applicare semplicemente la funzione desiderata al changeset,

def changeset(post, params \\ :empty) do 
    post 
    |> cast(params, @required_params, @optional_params) 
    |> validate_length(:title, min: 3) 
    |> validate_length(:metadata, min: 3) 
    |> implement_a_before_callback 
end 

def implement_a_before_callback(changeset) 
    #Apply required actions and return Changeset 
end 

Un altro modo, è quello di raggruppare più operazioni pronti contro termine insieme con Ecto.Multi. From the docs

Ecto.Multi consente di impacchettare operazioni che devono essere eseguite insieme (in una singola transazione di database) e offre un modo per analizzare le operazioni in coda senza eseguirle effettivamente. Ad ogni operazione viene assegnato un nome univoco che identificherà il risultato o aiuterà a identificare il punto di errore nel caso in cui si verifichi. Quindi, ogni volta che si desidera che un gruppo di operazioni correlate ai dati avvenga contemporaneamente, è possibile utilizzare Multi, qui è possibile sostituire entrambe le richiamate before_ e after_.

Un esempio potrebbe essere

# In defmodule Service 
    def password_reset(account, params) do 
    Multi.new 
    |> Multi.update(:account, Account.password_reset_changeset(account, params)) 
    |> Multi.insert(:log, Log.password_reset_changeset(account, params)) 
    |> Multi.delete_all(:sessions, assoc(account, :sessions)) 
    end 

Run utilizzando

result = Repo.transaction(Service.password_reset(account, params)) 

Bisogna ricordare che è necessario eseguire query di dati relativi e non fare altri lavori, come inviare una e-mail. Per questo puoi semplicemente creare una corrispondenza con il risultato ed eseguire l'azione appropriata. Consente seduti si voleva inviare una mail se l'operazione ha avuto successo e visualizzare alcune messaggio di errore se non

case result do 
    {:ok, %{account: account, log: log, sessions: sessions}} -> 
    # Operation was successful, perform actions like sending a mail 
    {:error, failed_operation, failed_value, changes_so_far} -> 
    # One of the operations failed. Raise error message 
end 

Fonte:

+1

Questo è il modo! La risposta accettata è obsoleta. – LukeS

Problemi correlati