I wonder if there is a way to create form objects with Elixir
and Phoenix
framework? I want to implement something similar to what reform
gem does in Rails
because I don't like having same validations run in every case, it leads to a complicated code in my experience. So could I create something like the following and make it work somehow?
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
This can work on a schema with virtual attributes:
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
This can also work if you specify an __changeset__
function or value in your struct (this is auto-generated by the schema
macro.) - however it seems like this may not be an intentional way to do it.
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
Both give the following results:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With