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 https://github.com/CargoSense/vex
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
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Is there a way to rollback a specific migration and only that one ("skipping" all the other ones)?
Would
mix ecto.rollback -v 2008090...
New
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
Hi all,
I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.
I'm trying to use Postg...
New
Hi all,
Trying to get some more clarity over utc_datetime and naive_datetime for Ecto:
https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
I have followed this StackOverflow post to install the specific version of Erlang.
And When I am running mix ecto.setup then getting fol...
New
Hi,
I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
Hi! May someone helps me, please!
I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Other popular topics
Hi All,
I set a environment variables in dev.exs , like below code.
when i start server, how can i set the ${enable} value?
thanks.
d...
New
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
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
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
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar.
I p...
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
What is the proper way to load a module from a file in to IEX?
In the python world, doing something like this pretty standard:
from ....
New
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something…
Haskell reminds me of Java, and e...
New
Hi!
Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New







