### Install assets dependencies with mix assets.setup
Source: https://github.com/enoonan/ash_backpex/blob/main/demo/README.md
Run this command to install the project's asset dependencies.
```bash
mix assets.setup
```
--------------------------------
### Run the Phoenix demo
Source: https://github.com/enoonan/ash_backpex/blob/main/CONTRIBUTING.md
Sets up and starts the Phoenix demo application, which depends on the local AshBackpex package.
```bash
cd demo
mix setup
mix phx.server
```
--------------------------------
### Install dependencies with mix deps.get
Source: https://github.com/enoonan/ash_backpex/blob/main/demo/README.md
Run this command to install the project's Elixir dependencies.
```bash
mix deps.get
```
--------------------------------
### Start the server with mix phx.server
Source: https://github.com/enoonan/ash_backpex/blob/main/demo/README.md
Starts the Phoenix server. After running, visit the admin interface at http://localhost:4000/.
```bash
mix phx.server
```
--------------------------------
### Create and migrate database with mix ecto.create and mix ecto.migrate
Source: https://github.com/enoonan/ash_backpex/blob/main/demo/README.md
These commands create the database and run migrations. They are part of the setup workflow.
```bash
mix ecto.create
```
```bash
mix ecto.migrate
```
--------------------------------
### Set up and test AshBackpex
Source: https://github.com/enoonan/ash_backpex/blob/main/CONTRIBUTING.md
Clones the repository, installs dependencies, and runs the test suite. Requires Elixir 1.18 or later; the CI baseline uses Erlang/OTP 26.
```bash
git clone https://github.com/enoonan/ash_backpex.git
cd ash_backpex
mix deps.get
mix test
```
--------------------------------
### Router Setup for Admin Routes
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Defines an admin scope routing to a LiveView resource for Backpex. Pipe through browser and admin auth before reaching the live route.
```elixir
scope "/admin", MyAppWeb.Admin do
pipe_through [:browser, :admin_auth]
live "/posts", PostLive
end
```
--------------------------------
### Set default sort order with init_order
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Sets the default sort order for the index view. The example orders by :inserted_at descending.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
init_order %{by: :inserted_at, direction: :desc}
end
```
--------------------------------
### Preload relationships with `load` in Backpex resource
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Use the `load` option inside the `backpex` block to preload relationships, calculations, or aggregates. The example preloads `:author`, `:comments`, and nested `:author` for comments.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
load [:author, :comments, nested: [:author]]
fields do
field :author
end
end
```
--------------------------------
### Organize form fields into panels
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Organizes form fields into named panels. The example defines 'Content' and 'Settings' panels and assigns the :title field to :content and the :published field to :settings.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
panels [
content: "Content",
settings: "Settings"
]
fields do
field :title do
panel :content
end
field :published do
panel :settings
end
end
end
```
--------------------------------
### Customize item actions with `item_actions` block
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Use the `item_actions` block to add or remove per-item actions. The example strips the default delete action and adds a custom archive action.
```elixir
item_actions do
strip_default [:delete] # Remove default delete action
action :archive, MyApp.ItemActions.Archive # Add custom action
end
```
--------------------------------
### Add filters to index view with `filters` block
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Define filters for the index view using the `filters` block. Each filter specifies a module and optionally a custom label. The example includes a boolean filter for `:published` and a select filter for `:status` with label "Post Status".
```elixir
filters do
filter :published do
module Backpex.Filters.Boolean
end
filter :status do
module Backpex.Filters.Select
label "Post Status" # Optional custom label
end
end
```
--------------------------------
### Specify custom Ash actions in Backpex resource
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Override the default Ash actions by specifying custom action names inside the `backpex` block. The example sets `create_action`, `read_action`, `update_action`, and `destroy_action`.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
create_action :admin_create
read_action :admin_read
update_action :admin_update
destroy_action :soft_delete
end
```
--------------------------------
### Provide custom changeset function in Backpex resource
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Define a custom changeset function for advanced control over create and update operations. The function receives `item`, `params`, and `metadata` (with `:assigns` and `:target` keys). The example uses `Ash.Changeset.for_create` with an actor from assigns.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
create_changeset fn item, params, metadata ->
assigns = Keyword.get(metadata, :assigns)
Ash.Changeset.for_create(item.__struct__, :create, params,
actor: assigns.current_user
)
end
end
```
--------------------------------
### Normalized embedded attribute shape
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Example of a section with one column normalized to the Ash attribute shape. The `*_order`, `*_delete`, and `*_move_*` keys are form controls and do not reach the Ash action.
```elixir
%{
"sections" => [
%{
"title" => "Hero",
"columns" => [
%{
"heading" => "Welcome",
"target" => %{"kind" => "internal", "path" => "/welcome"}
}
]
}
]
}
```
--------------------------------
### Create admin layout with Backpex app_shell
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Defines an admin layout using Backpex's `app_shell/1` component. This layout is used by AshBackpex LiveResources. It includes a sidebar with a Posts item and a topbar with theme selector and dropdown. The `admin/1` function is the layout entry point.
```elixir
# lib/my_app_web/components/layouts.ex
defmodule MyAppWeb.Layouts do
use MyAppWeb, :html
import Backpex.HTML.Layout
attr :flash, :map, required: true
attr :fluid?, :boolean, default: false
attr :current_url, :string, required: true
attr :socket, :any, required: true
attr :current_theme, :string, required: true
attr :sidebar_open, :boolean, required: true
attr :preferences_manifest, :map, required: true
slot :inner_block, required: true
def admin(assigns) do
~H"""
<.app_shell
socket={@socket}
fluid={@fluid?}
sidebar_open={@sidebar_open}
preferences_manifest={@preferences_manifest}
>
<:sidebar_branding>
<.sidebar_branding title="My App" />
<:topbar>
<.theme_selector
current_theme={@current_theme}
themes={[{"Light", "light"}, {"Dark", "dark"}]}
/>
<.topbar_dropdown>
<:label>
<.link href={~p"/"} class="flex justify-between hover:bg-base-200">
Back to App
<:sidebar>
<.sidebar_item current_url={@current_url} navigate={~p"/admin/posts"}>
Posts
<%!-- Add more sidebar items for your resources --%>
<.flash_messages flash={@flash} />
{render_slot(@inner_block)}
"""
end
end
```
--------------------------------
### Run mix ci for completion gate
Source: https://github.com/enoonan/ash_backpex/blob/main/AGENTS.md
Runs the repository completion gate, which is the same contract used by CI. Run this before handing off a completed change.
```bash
mix ci
```
--------------------------------
### Add admin routes for PostLive
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Adds admin routes for the PostLive LiveResource. It imports Backpex.Router, defines a scope under `/admin`, pipes through the browser pipeline, and uses `backpex_routes()` and a live_session with `Backpex.InitAssigns` to mount the LiveResource.
```elixir
# lib/my_app_web/router.ex
import Backpex.Router
scope "/admin", MyAppWeb.Admin do
pipe_through [:browser]
backpex_routes()
live_session :backpex_admin, on_mount: [Backpex.InitAssigns] do
live_resources "/posts", PostLive
end
end
```
--------------------------------
### Create PostLive LiveResource with AshBackpex
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Creates a LiveResource module for the Post resource using AshBackpex.LiveResource. It specifies the resource, layout, and fields to display in the admin interface. The `content` field uses the Backpex.Fields.Textarea module.
```elixir
# lib/my_app_web/live/admin/post_live.ex
defmodule MyAppWeb.Admin.PostLive do
use AshBackpex.LiveResource
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
fields do
field :title
field :content do
module Backpex.Fields.Textarea
end
field :published
field :inserted_at
end
end
end
```
--------------------------------
### Use server-assigned theme in root layout
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Sets the HTML theme attribute in your root layout to use the server-assigned theme. Falls back to "light" if no theme is assigned.
```heex
```
--------------------------------
### Configure pagination with per_page_default and per_page_options
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Configures pagination: sets the default page size to 25 and offers options of 10, 25, 50, and 100 items per page.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
per_page_default 25
per_page_options [10, 25, 50, 100]
end
```
--------------------------------
### Define a Backpex live resource for an Ash resource
Source: https://github.com/enoonan/ash_backpex/blob/main/README.md
Define a Backpex live resource for an Ash resource. Configure the resource, load relationships, set a layout, and declare fields with custom display and live resource options.
```elixir
# myapp_web/live/admin/post_live.ex
defmodule MyAppWeb.Live.Admin.PostLive do
use AshBackpex.LiveResource
backpex do
resource MyApp.Blog.Post
load [:author]
layout &MyAppWeb.Layouts.admin/1
fields do
field :title
field :published_at
field :author do
display_field(:name)
live_resource(MyAppWeb.Live.Admin.AuthorLive)
end
end
end
end
```
--------------------------------
### Create a LiveResource with backpex block
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Required for every AshBackpex LiveResource. The backpex block must include a resource (Ash resource module) and a layout (LiveView layout as a {Module, :function} tuple or function capture). Fields are declared inside the fields block.
```elixir
defmodule MyAppWeb.Admin.PostLive do
use AshBackpex.LiveResource
backpex do
resource MyApp.Blog.Post # Required: Ash resource module
layout {MyAppWeb.Layouts, :admin} # Required: LiveView layout
fields do
field :title
field :content
end
end
end
```
--------------------------------
### Persist index state with persist option
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Opts into index-state persistence for the listed settings (order, filters, columns, metrics). Requires the application layout to use Backpex's preference-enabled app shell and the router to include backpex_routes().
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
persist [:order, :filters, :columns, :metrics]
end
```
--------------------------------
### Display relationships with navigation links
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Configures a resource to preload the :author relationship and display it with a navigation link to the UserLive resource. Uses display_field :name and live_resource MyAppWeb.Admin.UserLive.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
load [:author] # Preload the relationship
fields do
field :title
field :author do
display_field :name
live_resource MyAppWeb.Admin.UserLive
end
end
end
```
--------------------------------
### Run focused tests
Source: https://github.com/enoonan/ash_backpex/blob/main/CONTRIBUTING.md
Runs focused tests for the adapter and the DSL, fields, forms, and filters test aliases. Useful when developing a specific behavior change.
```bash
mix test test/ash_backpex/adapter_test.exs
mix test.dsl
mix test.fields
mix test.forms
mix test.filters
```
--------------------------------
### Add ash_backpex dependency to mix.exs
Source: https://github.com/enoonan/ash_backpex/blob/main/README.md
Add the ash_backpex dependency to your mix.exs file. Use the latest version compatible with your project.
```elixir
def deps do
[
{:ash_backpex, "~> 0.2.0"}
]
end
```
--------------------------------
### Configure LiveResource with InlineCRUD for comments
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Configures the PostLive LiveResource to use the admin actions, load the comments relationship, and define an InlineCRUD field for :comments. The child_fields define the fields shown for each comment, including a textarea for body, a typeahead for author, a select for sentiment, and a checkbox for approved. The author typeahead resolves Demo.Blog.Comment.author, not a relationship on the parent post. live_resource DemoWeb.CommentLive enables linking to show pages in read-only view.
```elixir
defmodule DemoWeb.PostLive do
use AshBackpex.LiveResource
backpex do
resource Demo.Blog.Post
create_action :admin_create
update_action :admin_update
load [:author, :comments, :topic_tags, :audience_tags, :word_count, :comment_count]
panels(
content: "Content",
publishing: "Publishing",
relationships: "Relationships"
)
fields do
field :comments do
module Backpex.Fields.InlineCRUD
except [:index]
live_resource DemoWeb.CommentLive
panel :relationships
child_fields do
field :body, Backpex.Fields.Textarea do
label "Body"
rows 3
end
field :author do
label "Author"
display_field :name
typeahead true
typeahead_limit 10
prompt "Choose an author"
class "w-56"
end
field :sentiment do
label "Sentiment"
options Positive: :positive, Neutral: :neutral, Critical: :critical
class "w-40"
end
field :approved do
label "Approved"
class "w-28"
end
end
end
end
end
end
```
--------------------------------
### Define admin actions with manage_relationship for comments
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Defines :admin_create and :admin_update actions on the Post resource. Each action accepts a :comments argument as an array of maps and uses manage_relationship with type: :direct_control. :direct_control creates new comments, updates existing ones by primary key, and destroys omitted comments. The update action sets require_atomic? false.
```elixir
defmodule Demo.Blog.Post do
use Ash.Resource,
domain: Demo.Blog,
data_layer: AshSqlite.DataLayer
actions do
create :admin_create do
# Post attributes and other relationship arguments are omitted here.
argument :comments, {:array, :map}, allow_nil?: true
change manage_relationship(:comments, type: :direct_control)
end
update :admin_update do
# Post attributes and other relationship arguments are omitted here.
require_atomic? false
argument :comments, {:array, :map}, allow_nil?: true
change manage_relationship(:comments, type: :direct_control)
end
end
end
```
--------------------------------
### Set singular and plural display names
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Customizes the singular and plural display names for the resource in the admin UI. Use when the default resource name is not suitable for display.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
singular_name "Blog Post"
plural_name "Blog Posts"
end
```
--------------------------------
### Read-Only Admin Resource Configuration
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Defines an admin resource for a read-only audit log. Strips the default edit and delete actions and displays the specified fields.
```elixir
backpex do
resource MyApp.AuditLog
layout {MyAppWeb.Layouts, :admin}
item_actions do
strip_default [:edit, :delete]
end
fields do
field :action
field :user
field :inserted_at
end
end
```
--------------------------------
### Define embedded resources and parent Post for recursive InlineCRUD
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Defines the embedded resources (ContentTarget, ContentColumn, ContentSection) and the parent Post resource for recursive embedded configuration. Each embedded resource uses `data_layer: :embedded` and the parent's `:sections` attribute is an array of ContentSection. The create and update actions must accept the root `:sections` attribute; the update action sets `require_atomic? false`.
```elixir
defmodule Demo.Blog.ContentTarget do
use Ash.Resource, data_layer: :embedded
attributes do
attribute :kind, :atom, public?: true, constraints: [one_of: [:internal, :external]]
attribute :path, :string, public?: true
end
end
defmodule Demo.Blog.ContentColumn do
use Ash.Resource, data_layer: :embedded
attributes do
attribute :heading, :string, public?: true
attribute :target, Demo.Blog.ContentTarget, public?: true
end
end
defmodule Demo.Blog.ContentSection do
use Ash.Resource, data_layer: :embedded
attributes do
attribute :title, :string, public?: true
attribute :columns, {:array, Demo.Blog.ContentColumn}, default: [], public?: true
end
end
defmodule Demo.Blog.Post do
use Ash.Resource, domain: Demo.Blog, data_layer: AshSqlite.DataLayer
attributes do
attribute :sections, {:array, Demo.Blog.ContentSection}, default: [], public?: true
end
actions do
create :admin_create do
accept [:title, :sections]
end
update :admin_update do
require_atomic? false
accept [:title, :sections]
end
end
end
```
--------------------------------
### Configure recursive InlineCRUD field DSL for sections
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Configures the root `:sections` field in the parent LiveResource using Backpex.Fields.InlineCRUD and AshBackpex.Fields.Embedded. This is the complete DSL shape used by the demo; AshBackpex infers `type: :embed` for repeated embedded nodes and derives child fields from the resource at each depth.
```elixir
field :sections do
module Backpex.Fields.InlineCRUD
child_fields do
field :columns do
module Backpex.Fields.InlineCRUD
child_fields do
field :heading
field :target do
module AshBackpex.Fields.Embedded
child_fields do
field :kind
field :path
end
end
end
end
end
end
```
--------------------------------
### Add filters to the index view
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Adds boolean and select filters to the index view using Backpex.Filters.Boolean and Backpex.Filters.Select modules.
```elixir
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
fields do
field :title
field :published
field :status
end
filters do
filter :published do
module Backpex.Filters.Boolean
end
filter :status do
module Backpex.Filters.Select
end
end
end
```
--------------------------------
### Define child resource with create/update actions for InlineCRUD
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Defines the child resource with attributes, relationships, and actions required for InlineCRUD. The `create` and `update` actions accept the fields submitted by the repeated form: `body`, `sentiment`, `approved`, `post_id`, and `author_id`.
```elixir
defmodule Demo.Blog.Comment do
use Ash.Resource,
domain: Demo.Blog,
data_layer: AshSqlite.DataLayer
attributes do
uuid_primary_key :id
attribute :body, :string do
allow_nil? false
public? true
end
attribute :sentiment, :atom do
allow_nil? false
default :neutral
public? true
constraints one_of: [:positive, :neutral, :critical]
end
attribute :approved, :boolean do
allow_nil? false
default false
public? true
end
end
relationships do
belongs_to :post, Demo.Blog.Post do
allow_nil? false
end
belongs_to :author, Demo.Blog.Author do
allow_nil? false
end
end
actions do
defaults [:read, :destroy]
create :create do
primary? true
accept [:body, :sentiment, :approved, :post_id, :author_id]
end
update :update do
primary? true
accept [:body, :sentiment, :approved, :post_id, :author_id]
end
end
end
```
--------------------------------
### Control field visibility with only and except
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Use only to show a field on specific views and except to hide it from specific views. The comments indicate the effect of each option.
```elixir
field :inserted_at do
only [:index, :show] # Only show on index and show views
end
field :internal_notes do
except [:index] # Hide from index view
end
```
--------------------------------
### Enable search on string fields
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Set searchable true on a string field to enable search functionality.
```elixir
field :title do
searchable true
end
```
--------------------------------
### Configure custom field type mappings
Source: https://github.com/enoonan/ash_backpex/blob/main/README.md
Configure custom field type mappings globally or with a function for conditional logic. The function receives the type and constraints, returning a Backpex field module or nil to fall back to defaults.
```elixir
# config/config.exs
# Global config (applies to all apps using AshBackpex)
config :ash_backpex,
field_type_mappings: %{
MyApp.Types.Money => Backpex.Fields.Currency,
MyApp.Types.RichText => Backpex.Fields.Textarea
}
# Or use a function for conditional logic
config :ash_backpex,
field_type_mappings: fn type, constraints ->
case type do
MyApp.Types.Money -> Backpex.Fields.Currency
_ -> nil # Fall back to default
end
end
```
--------------------------------
### Declare basic fields in backpex fields block
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Declares fields that can reference attributes, relationships, calculations, or aggregates. AshBackpex auto-detects the Backpex field type from the Ash type or relationship cardinality.
```elixir
fields do
field :title # Simple attribute
field :author # Relationship (auto-detects BelongsTo)
field :word_count # Calculation
field :comment_count # Aggregate
end
```
--------------------------------
### Custom Date Display Format
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Sets a custom display format for a date field, formatting it in a human-readable style with both date and time.
```elixir
field :published_at do
format "%B %d, %Y at %H:%M"
end
```
--------------------------------
### Configure relationship field with display_field and live_resource
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Configures a relationship field. display_field specifies which attribute of the related record to show; live_resource enables navigation links to that resource's LiveView. The generated options_query derives from the Ash relationship's filter, sort, and default_sort settings.
```elixir
field :author do
display_field :name # Field to display from related record
live_resource MyAppWeb.Admin.UserLive # Enables navigation links
end
```
--------------------------------
### Rich Text Field with Textarea
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Configures a field to use the Backpex Textarea module for long-form content, with a specified number of rows.
```elixir
field :content do
module Backpex.Fields.Textarea
rows 15
end
```
--------------------------------
### Configure has_many relationship with InlineCRUD
Source: https://github.com/enoonan/ash_backpex/blob/main/README.md
Use this snippet to configure a has_many relationship as an InlineCRUD field in a Backpex form. The child_fields DSL defines the fields for the child records. AshBackpex derives child modules and relationship options from the related child resource, adds move-up and move-down controls, and preserves child primary keys for updates. The parent Ash actions must expose an array-of-maps argument and use manage_relationship, typically with type: :direct_control.
```elixir
field :rows do
module Backpex.Fields.InlineCRUD
except [:index]
child_fields do
field :title
field :config, Backpex.Fields.Textarea do
label "Configuration"
end
field :category do
display_field :name
typeahead true
end
end
end
```
--------------------------------
### Configure typeahead for belongs_to field with display_field, typeahead_limit, debounce, and prompt
Source: https://github.com/enoonan/ash_backpex/blob/main/README.md
Configure a server-backed typeahead for a belongs_to relationship field. The search uses display_field and preserves the relationship's Ash filter, sort, read action, context, actor, tenant, and authorization through the generated options_query. Opening the dropdown preloads up to typeahead_limit options; typing replaces them with matching results.
```elixir
field :author do
display_field :name
typeahead true
typeahead_limit 10
debounce 300
prompt "Choose an author"
end
```
--------------------------------
### Make fields searchable with searchable true
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/getting-started.md
Adds the searchable true option to fields to enable the search box. The content field also specifies the Backpex.Fields.Textarea module.
```elixir
fields do
field :title do
searchable true
end
field :content do
searchable true
module Backpex.Fields.Textarea
end
end
```
--------------------------------
### Override field module with Backpex.Fields.Textarea
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Overrides the auto-detected field module when the default mapping is not sufficient. Use this to explicitly set the Backpex field module for a field.
```elixir
field :content do
module Backpex.Fields.Textarea
end
```
--------------------------------
### Configure nested InlineCRUD for embedded resources
Source: https://github.com/enoonan/ash_backpex/blob/main/README.md
Use this snippet to configure nested InlineCRUD fields for typed embedded Ash resources. The child_fields DSL is recursive, and each nested field is derived against its immediate embedded resource. Repeated embedded children use InlineCRUD with an inferred type: :embed, while singular embedded children use AshBackpex.Fields.Embedded.
```elixir
field :sections do
module Backpex.Fields.InlineCRUD
child_fields do
field :title
field :columns do
module Backpex.Fields.InlineCRUD
child_fields do
field :heading
field :target do
module AshBackpex.Fields.Embedded
child_fields do
field :kind
field :path
end
end
end
end
end
end
```
--------------------------------
### Configure InlineCRUD for has_many child fields
Source: https://github.com/enoonan/ash_backpex/blob/main/usage-rules.md
Use Backpex.Fields.InlineCRUD to opt into repeated child forms for a has_many relationship. Configure child fields with the child_fields block, including typeahead and display_field options. The parent create/update action must accept an {:array, :map} argument and connect it to the relationship with manage_relationship.
```elixir
field :rows do
module Backpex.Fields.InlineCRUD
except [:index]
child_fields do
field :title
field :position
field :category do
display_field :name
typeahead true
end
end
end
```
```elixir
argument :rows, {:array, :map}, allow_nil?: false, default: []
change manage_relationship(:rows, type: :direct_control)
```
--------------------------------
### Define has_many relationship on parent resource
Source: https://github.com/enoonan/ash_backpex/blob/main/guides/inline-crud.md
Defines the parent resource with a `has_many` relationship to the child resource. This is the first step in setting up InlineCRUD for repeated child forms.
```elixir
defmodule Demo.Blog.Post do
use Ash.Resource,
domain: Demo.Blog,
data_layer: AshSqlite.DataLayer
relationships do
has_many :comments, Demo.Blog.Comment
end
end
```