2016-04-27 5 views
1

So eine schnelle async Benutzernamen Validierungsprüfung Ich schreibe, und im Anschluss an das Tutorial auf PhoenixFrameworks Website, kann ich es tun wie so:Wie Bindung der Parameter in PhoenixFramework (Elixir) arbeiten

def validateUsername(conn, %{"username" => user}) do 
    IO.inspect(conn) 
    query = from u in User, 
     where: u.username == ^user, 
     select: [u.username] 

    case Repo.all(query) do 
     [[username]] -> 
     conn 
     |> json(%{ success: false, error: "Username has been taken" }) 
     [] -> 
     conn 
     |> json(%{ success: true }) 
     nil -> 
     conn 
     |> json(%{ success: true }) 
     _ -> 
     conn 
     |> json(%{ success: false, error: "Internal Server Error"}) 
    end 

Aber diese macht für mich keinen Sinn, da ich mich nie mit einer funktionalen Programmiersprache beschäftigt habe, und ich weiß, dass die Datenbindung mit = im Elixier anders funktioniert. Aber in meinem Kopf fühle ich mich wie es wie rückgängig gemacht werden soll:

def validateUsername(conn, %{user => "username"}) 

Oder so ähnlich, so meine Hauptfrage ist

Wie funktioniert die %{"username" => user}) die user Variable mit den relevanten Informationen füllen?

+0

Pattern Matching enthält, ist auf der funktionalen Programmierung nicht inhärent. Es ist nur ein prominentes Merkmal in vielen FP-Sprachimplementierungen. –

Antwort

2

Pattern Matching gedacht werden kann als eine Sache, die alle Variablen auf der linken Seite des Ausdrucks zuweist, wenn die rechte Seite "die richtige Form" hat.

{a, b} = {1, 2} # now a = 1, b = 2 
%{"username" => user} = %{"username" => "Tomasz", "password" => "secret"} # now user = "Tomasz" 
[a, b, c] = [:a, "b", 1] # a = :a, b = :b, c = 1 
{a, b} = {1, 2, 3} # error 

Und es funktioniert auch für verschachtelte Daten!

{[a, b, 3], {c, 5}} = {[1, 2, 3], {4, 5}} 

Es ist eine wirklich umfassende Anleitung zur Mustererkennung in "Programmierung Phoenix", die auch pin operator

2

Wie füllt die %{"username" => user}) die Benutzervariable mit den relevanten Informationen?

So funktioniert Mustererkennung in Elixir. Der Schlüssel sollte mit dem Schlüssel in der Karte übereinstimmen, und der Wert sollte ein Muster sein, das mit dem Wert dieses Schlüssels in der Karte abgeglichen wird. Wenn es sich um eine normale Variable handelt, wird ihr nur der Wert zugewiesen.

Auch unter der Annahme Ihrer Datenbank eine eindeutige Einschränkung für Benutzernamen in der Benutzertabelle hat, würde ich Ihren ursprünglichen Code umschreiben Repo.get_by/2 zu verwenden:

def validateUsername(conn, %{"username" = user}) do 
    case Repo.get_by(User, username: user) do 
    nil -> 
     conn 
     |> json(%{ success: true }) 
    user -> 
     conn 
     |> json(%{ success: false, error: "Username has been taken" }) 
    end 
end 

oder

def validateUsername(conn, %{"username" = user}) do 
    if Repo.get_by(User, username: user) do 
    conn 
    |> json(%{ success: false, error: "Username has been taken" }) 
    else 
    conn 
    |> json(%{ success: true }) 
    end 
end 
Verwandte Themen