sewer_r4t
Simple Validation without Ecto
Any Simple validation like checking two fields if the same without Ecto, and Schema
Marked As Solved
chokchit
You can use this GitHub - CargoSense/vex: Data Validation for Elixir · GitHub
2
Also Liked
gutschilla
If it’s really just two params that shall be the same (like password and it’s repetition), one might consider a plain pattern match and a guard that assures that two fields are the same and not nil.
def some_action(conn, %{"field_1" => value, "field_2" => value})
when not is_nil(value) do
# do something with value
end
def some_action(conn, _params) do
# render "field_1 must be equal to field_""
end
For JSON payloads I’d use a JSON schema to validate against.
2
peerreynders
A contrived example
# file: lib/form_demo_web/controllers/page_controller.ex
#
defmodule FormDemoWeb.PageController do
use FormDemoWeb, :controller
# Store user form data under conn.params["user"]
def index(conn, params) do
# Data to preload form with
user = %{"name" => "Bruce", "username" => "redrapids"}
conn
|> update_user(user) # add "user" to conn
|> render("index.html")
end
def update(conn, %{"user" => user}) do
case validate_user(user) do
{:ok, user} ->
conn
|> update_user(user)
|> put_flash(:info, "Updated to #{user["name"]}, #{user["username"]}!")
|> render("index.html")
{:error, errors} ->
render(conn, "index.html", errors: errors)
end
end
# Make data available under conn.params["user"]
# for Phoenix.HTML.Form.form_for/4
#
# Plug.Conn implements Phoenix.HTML.FormData used by form_for/4
#
defp update_user(conn, user),
do: Map.update!(conn, :params, &Map.put(&1, "user", user))
defp validate_user(user) do
errors =
[]
|> check_value(user, :name)
|> check_value(user, :username)
case errors do
[] ->
{:ok, user}
_ ->
{:error, errors}
end
end
def check_value(errors, user, key) do
cond do
Map.get(user, Atom.to_string(key), "") == "" ->
# format expected by FormDemoWeb.ErrorHelpers.error_tag/2
[{key, {"can't be blank", []}} | errors]
true ->
errors
end
end
end
# file: lib/form_demo_web/router.ex
#
defmodule FormDemoWeb.Router do
use FormDemoWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", FormDemoWeb do
pipe_through :browser
get "/", PageController, :index
post "/", PageController, :update # <- Added to validate form data
end
end
# file: lib/form_demo_web/views/page_view.ex
#
defmodule FormDemoWeb.PageView do
use FormDemoWeb, :view
def get_errors(%Plug.Conn{assigns: %{errors: errors}}) when is_list(errors),
do: errors
# FormDemoWeb.ErrorHelpers.error_tag/2 needs a list
def get_errors(_),
do: []
def errors?(%Phoenix.HTML.Form{errors: [_ | _]}),
# non-empty list of errors
do: true
def errors?(_),
do: false
end
<!-- file: lib/form_demo_web/templates/page/index.html.eex -->
<!--
Phoenix.HTML.Form.form_for/4
Phoenix.HTML.Form.text_input/3
Phoenix.HTML.Form.submit/1
@conn --- Plug.Conn implements Phoenix.HTML.FormData protocol
Routes.page_path(@conn, :update) --- generates the URL to PageController.update/2
[as: :user] --- form data is stored under conn.params["user"]
[errors: get_errors(@conn)] --- extracts the errors for the conn to include it in the Phoenix.HTML.Form struct
errors?/1, get_errors/1 --- defined under FormDemoWeb.PageView
error_tag/2 --- from generated module FormDemoWeb.ErrorHelpers
-->
<h1>Current User</h1>
<%= form_for @conn, Routes.page_path(@conn, :update), [as: :user, method: "post", errors: get_errors(@conn)], fn form -> %>
<%= if errors?(form) do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<div>
<%= text_input form, :name, placeholder: "Name" %>
<%= error_tag form, :name %>
</div>
<div>
<%= text_input form, :username, placeholder: "Username" %>
<%= error_tag form, :username %>
</div>
<%= submit "Update User" %>
<% end %>
<!DOCTYPE html>
<html lang="en">
<!-- file: lib/form_demo_web/templates/layout/app.html.eex -->
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>FormDemo · Phoenix Framework</title>
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
</head>
<body>
<main role="main" class="container">
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<%= render @view_module, @view_template, assigns %>
</main>
<script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
</body>
</html>
1
Popular in Questions
If I have a post route which an argument:
post /my_post_route/:my_param1, MyController.my_post_handler
How would get the post params ...
New
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone.
What strikes me is th...
New
After calling mix ecto.create I get this error:
17:00:32.162 [error] GenServer #PID<0.412.0> terminating
** (Postgrex.Error) FATAL...
New
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)?
Would
mix ecto.rollback -v 200809061...
New
The Elixir Typespec docs show the following syntax for keyword lists in typespecs:
# ...
| [key: type] # keyword lists...
New
Hello, how can I check the Phoenix version ?
Thanks !
New
Hi,
I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
I have a super simple question about elixir - how would I take a file like this
foo
bar
baz
and output a new file that enumerates th...
New
Other popular topics
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Hello guys,
I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I’m writing a test for one of the...
New
Credo is smart enough to check for (something like) this:
assert length(the_list) == 0
with this response:
Checking if an enum is empt...
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
Hi!
In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir?
Searched the docs for ip address and the web, no good results.
Thanks!
New
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition)
It’s been a while since we first asked this, I...
New
I am trying to run a deploy with docker and I successfully runned with this command:
docker build -t romenigld/blog-prod .
but when I t...
New
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New








