elixir-lang/ecto — pull request #301 by lexmag (2014-10-12 19:47:26+00:00)
Title: Return validation errors as maps

Closes #286
It changes generated really more sophisticated code then previous one:
```elixir
struct(user, age: present() and greater_than(18) when user.name != "jose")
```
```elixir
if(user.name() != "jose") do
present(:age, Map.get(var, :age)) ++ greater_than(:age, Map.get(var, :age), 18)
else
[]
end
# vs
if(user.name() != "jose") do
case({acc = case({acc = %{}, greater_than(:age, Map.get(var, :age), 18)}) do
{_, []} ->
acc
{%{age: msgs}, [{_, msg}]} ->
Map.put(acc, :age, [msg | msgs])
{_, [{_, msg}]} ->
Map.put(acc, :age, [msg])
end, present(:age, Map.get(var, :age))}) do
{_, []} ->
acc
{%{age: msgs}, [{_, msg}]} ->
Map.put(acc, :age, [msg | msgs])
{_, [{_, msg}]} ->
Map.put(acc, :age, [msg])
end
else
%{}
end
```

One of the possible pros is that we can simplify current interface for predicates:
```elixir
# from
def image_attachments(attr, value, opts \\ []) do
if Path.extname(value) in ~w(jpg gif png) do
[]
else
[{attr, opts[:message] || "is not an image attachment"}]
end
end
# to
def image_attachments(attr, value, opts \\ []) do
if Path.extname(value) in ~w(jpg gif png) do
opts[:message] || "is not an image attachment"
end
end
```