Packages
formex
0.2.0
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Form library for Phoenix with Ecto support
Current section
Files
Jump to
Current section
Files
lib/builder.ex
defmodule Formex.Builder do
import Ecto.Changeset
alias Formex.Form
@repo Application.get_env(:formex, :repo)
@moduledoc """
The form builder.
Example:
```
form = create_form(App.ArticleType, %Article{})
render(conn, "new.html", form: form)
```
```
App.ArticleType
|> create_form(%Article{}, article_params)
|> insert_form_data
|> case do
{:ok, _article} ->
# ...
{:error, form} ->
# ...
end
```
"""
@doc """
Creates a form struct.
## Arguments
* `type` - the module that implements `Formex.Type`, for example: `App.ArticleType`
* `struct` - the struct that will be used in `Ecto.Changeset.cast`, for example: `%App.Article{}`
* `params` - params that will be used in `Ecto.Changeset.cast`
"""
@spec create_form(module, Ecto.Schema.t, Map.t) :: Form.t
def create_form(type, struct, params \\ %{}) do
%Form{
type: type,
struct: struct,
model: struct.__struct__,
params: params
}
|> type.build_form()
|> create_changeset(type)
# |> IO.inspect
end
@doc """
Invokes `Repo.insert`. In case of `:error` returns `{:error, form}` (with new `form.changeset`
value) instead of `{:error, changeset}` (as Ecto does)
"""
@spec insert_form_data(Form.t) :: {:ok, Ecto.Schema.t} | {:error, Form.t}
def insert_form_data(form) do
case @repo.insert(form.changeset) do
{:ok, schema} -> {:ok, schema}
{:error, changeset} -> {:error, Map.put(form, :changeset, changeset)}
end
end
@doc """
Invokes `Repo.update`. In case of `:error` returns `{:error, form}` (with new `form.changeset`
value) instead of `{:error, changeset}` (as Ecto does)
"""
@spec update_form_data(Form.t) :: {:ok, Ecto.Schema.t} | {:error, Form.t}
def update_form_data(form) do
case @repo.update(form.changeset) do
{:ok, schema} -> {:ok, schema}
{:error, changeset} -> {:error, Map.put(form, :changeset, changeset)}
end
end
#
defp create_changeset(form, type) do
changeset = form.struct
|> cast(form.params, get_normal_fields_names(form))
|> validate_required(get_required_fields_names(form))
|> type.changeset_after_create_callback
form
|> Map.put(:changeset, changeset)
end
defp get_normal_fields_names(form) do
form.fields
# |> Enum.filter(&(!&1.assoc))
|> Enum.map(&(&1.name))
end
# defp get_assoc_fields_names(form) do
# form.fields
# |> Enum.filter(&(&1.assoc))
# |> Enum.map(&(&1.name))
# end
defp get_required_fields_names(form) do
form.fields
|> Enum.filter(&(&1.required))
|> Enum.map(&(&1.name))
end
end