2015-08-13 9 views
10

Ich frage mich, ob es eine Möglichkeit gibt, Formularobjekte mit Elixir und Phoenix Framework zu erstellen? Ich möchte etwas ähnliches implementieren, was reform gem in Rails tut, weil ich nicht möchte, dass gleiche Validierungen in jedem Fall ausgeführt werden, führt es zu einem komplizierten Code in meiner Erfahrung. Also könnte ich etwas wie das Folgende erstellen und es irgendwie funktionieren lassen?Formularobjekte mit Elixir und Phoenix Framework

defmodule RegistrationForm do 
    defstruct email: nil, password: nil, age: nil  

    import Ecto.Changeset  

    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, ["email", "password", "age"], ~w()) 
    |> validate_length(:email, min: 5, max: 240)  
    |> validate_length(:password, min: 8, max: 240) 
    |> validate_inclusion(:age, 0..130)   
    end 

end 

Antwort

14

mit virtuellen Attributen auf ein Schema arbeitet Dies kann:

vom schema Makro
defmodule RegistrationForm do  
    use Ecto.Schema 

    import Ecto.Changeset 

    schema "" do 
    field :email, :string, virtual: true 
    field :password, :string, virtual: true 
    field :age, :integer, virtual: true 
    end 

    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, ["email", "password", "age"], ~w()) 
    |> validate_length(:email, min: 5, max: 240)  
    |> validate_length(:password, min: 8, max: 240) 
    |> validate_inclusion(:age, 0..130)   
    end 
end 

Dies kann auch funktionieren, wenn Sie eine __changeset__ Funktion oder den Wert in Ihrer Struktur angeben (dies ist automatisch generiert.) - Es scheint jedoch, dass dies kein absichtlicher Weg ist, dies zu tun.

defmodule RegistrationForm do 
    defstruct email: nil, password: nil, age: nil  

    import Ecto.Changeset 

    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, ["email", "password", "age"], ~w()) 
    |> validate_length(:email, min: 5, max: 240)  
    |> validate_length(:password, min: 8, max: 240) 
    |> validate_inclusion(:age, 0..130)   
    end 

    def __changeset__ do 
    %{email: :string, password: :string, age: :integer} 
    end 
end 

Beide geben die folgenden Ergebnisse:

iex(6)> RegistrationForm.changeset(%RegistrationForm{}, %{email: "[email protected]", password: "foobarbaz", age: 12}).valid? 
true 
iex(7)> RegistrationForm.changeset(%RegistrationForm{}, %{email: "[email protected]", password: "foobarbaz", age: 140}).valid? 
false 
+0

Ihnen sehr danken. Ich hoffe, es wird nicht nur für mich nützlich sein – JustMichael

+0

Kann ich dieses Formular für verschachtelte Modelle verwenden? Wie, wenn E-Mail und Passwort Felder für ein "Benutzer" -Modell sind und Alter ein Feld für ein "Profil" -Modell ist, das zu "Benutzer" gehört (und "Benutzer" hat ein "Profil")? – JustMichael

+0

@JustMichael Das Registrierungsformular ist an kein Modell gebunden. Wenn Sie die Felder für ein bestimmtes Modell herausholen wollen, dann können Sie Folgendes tun: 'struct (Benutzer, Dict.take (changeset, [: email,: password])' – Gazler

Verwandte Themen