Packages
ash_phoenix
2.3.22
2.3.24
2.3.23
2.3.22
2.3.21
2.3.20
2.3.19
2.3.18
2.3.17
2.3.16
2.3.15
2.3.14
2.3.13
2.3.12
2.3.11
2.3.10
2.3.9
2.3.8
2.3.7
2.3.6
2.3.5
2.3.4
2.3.3
2.3.2
2.3.1
2.3.0
2.2.0
2.1.26
2.1.25
2.1.24
2.1.23
2.1.22
2.1.21
2.1.20
2.1.19
2.1.18
2.1.17
2.1.16
2.1.15
2.1.14
2.1.13
2.1.12
2.1.11
2.1.10
2.1.9
2.1.8
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.8
2.0.0-rc.7
2.0.0-rc.6
2.0.0-rc.5
2.0.0-rc.4
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
1.3.7
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.26
1.2.25
1.2.24
1.2.23
1.2.22
1.2.21
1.2.20
1.2.19
1.2.18
1.2.17
1.2.16
1.2.15
1.2.14
1.2.13
1.2.12
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.1.0-rc.3
1.1.0-rc.2
1.1.0-rc.1
1.1.0-rc.0
1.0.0-rc.1
1.0.0-rc.0
1.0.0-pre.2
1.0.0-pre.1
1.0.0-pre.0
0.7.7
0.7.6-rc.0
0.7.5
0.7.4
0.7.3
0.7.2-rc.2
0.7.2-rc.1
0.7.2-rc.0
0.7.1
0.7.0
0.6.0-rc.7
0.6.0-rc.6
0.6.0-rc.5
0.6.0-rc.4
0.6.0-rc.3
0.6.0-rc.2
0.6.0-rc.1
0.6.0-rc.0
0.5.19-rc.2
0.5.19-rc.1
0.5.19-rc.0
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
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.24
0.4.23
0.4.23-rc.1
0.4.23-rc.0
0.4.22-rc2
0.4.22-rc1
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
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.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Utilities for integrating Ash and Phoenix
Current section
Files
Jump to
Current section
Files
usage-rules/form_integration.md
<!--
SPDX-FileCopyrightText: 2020 Zach Daniel
SPDX-License-Identifier: MIT
-->
# Form Integration
AshPhoenix provides `AshPhoenix.Form`, a powerful module for creating and handling forms backed by Ash resources.
## Creating Forms
```elixir
# For creating a new resource
form = AshPhoenix.Form.for_create(MyApp.Blog.Post, :create) |> to_form()
# For updating an existing resource
post = MyApp.Blog.get_post!(post_id)
form = AshPhoenix.Form.for_update(post, :update) |> to_form()
# Form with initial value
form = AshPhoenix.Form.for_create(MyApp.Blog.Post, :create,
params: %{title: "Draft Title"}
) |> to_form()
```
## Code Interfaces
Using the `AshPhoenix` extension in domains gets you special functions in a resource's
code interface called `form_to_*`. Use this whenever possible.
First, add the `AshPhoenix` extension to our domains and resources, like so:
```elixir
use Ash.Domain,
extensions: [AshPhoenix]
```
which will cause another function to be generated for each definition, beginning with `form_to_`.
For example, if you had the following,
```elixir
# in MyApp.Accounts
resources do
resource MyApp.Accounts.User do
define :register_with_password, args: [:email, :password]
end
end
```
you could then make a form with:
```elixir
MyApp.Accounts.form_to_register_with_password(...opts)
```
By default, the `args` option in `define` is ignored when building forms. If you want to have positional arguments, configure that in the `forms` section which is added by the `AshPhoenix` section. For example:
```elixir
forms do
form :register_with_password, args: [:email]
end
```
Which could then be used as:
```elixir
MyApp.Accounts.register_with_password(email, ...)
```
These positional arguments are *very important* for certain cases, because there may be values you do not want the form to be able to set. For example, when updating a user's settings, maybe the action takes a `user_id`, but the form is on a page for a specific user's id and so this should therefore not be editable in the form. Use positional arguments for this.
## Handling Form Submission
In your LiveView:
```elixir
def handle_event("validate", %{"form" => params}, socket) do
form = AshPhoenix.Form.validate(socket.assigns.form, params)
{:noreply, assign(socket, :form, form)}
end
def handle_event("submit", %{"form" => params}, socket) do
case AshPhoenix.Form.submit(socket.assigns.form, params: params) do
{:ok, post} ->
socket =
socket
|> put_flash(:info, "Post created successfully")
|> push_navigate(to: ~p"/posts/#{post.id}")
{:noreply, socket}
{:error, form} ->
{:noreply, assign(socket, :form, form)}
end
end
```