### 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 ```