sewer_r4t
Simple Validation without Ecto
Any Simple validation like checking two fields if the same without Ecto, and Schema
Marked As Solved
chokchit
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
Last Post!
sewer_r4t
Popular in Questions
Hi!
In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir?
Searched the docs for ip address and the web, no good results.
Thanks!
New
Hi there,
I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Lets say I have map like this fetching from my database
%{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
Hi everyone!
I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
Using vs code and installed ElixirLS: support and debugger.
And I got an error popped up on start up says
Failed to run ‘elixir’ comma...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Other popular topics
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set?
Thanks.
New
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum.
...
New
What is the idiomatic way of matching for not nil in Elixir?
E.g.,
First way:
defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Hello!
tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability.
After spen...
New
i’m a new one to elixir
which editor can i use
vs code? or atom?
Thanks! :smiley:
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









