Skip to content

Commit 2d2dc9d

Browse files
authored
Merge pull request #657 from avo-hq/cursor/document-belongs-to-actions-0da7
Document belongs_to behavior in actions
2 parents a048aa1 + 750fbd8 commit 2d2dc9d

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

docs/4.0/actions.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ You may use the [custom controls](./custom-controls.html) feature to show action
127127

128128
## Collect input with fields
129129

130-
An action can define fields, shown to the user in the action's modal. They work the same way as fields on resources. When the action runs on a single record the fields are hydrated from that record; otherwise they're plain form inputs. The submitted values arrive in `handle` as the `fields` argument.
130+
An action can define fields, shown to the user in the action's modal. Most work the same way as fields on resources. When the action runs on a single record the fields are hydrated from that record; otherwise fields that do not depend on a record render as plain form inputs. Association fields are an exception, as described below. The submitted values arrive in `handle` as the `fields` argument.
131131

132132
```ruby
133133
# app/avo/actions/toggle_inactive.rb
@@ -141,6 +141,47 @@ end
141141

142142
Check out the [Fields page](./fields.md) for everything fields can do.
143143

144+
### Choose an associated record in a collection action
145+
146+
A [`belongs_to` field](./associations/belongs_to.html) needs one current record to resolve its association. It works when you run the action from a record's <Show /> view or select exactly one record on the <Index /> view because Avo hydrates the action with that record. It cannot render when you select multiple records or run a standalone action because there is no single current record.
147+
148+
For a short list of choices, use a [`select` field](./fields/select.html) with options loaded when the form renders:
149+
150+
```ruby
151+
# app/avo/actions/assign_user.rb
152+
class Avo::Actions::AssignUser < Avo::BaseAction
153+
def fields
154+
field :user_id,
155+
as: :select,
156+
options: -> { User.order(:name).pluck(:name, :id) },
157+
include_blank: true
158+
end
159+
160+
def handle(query:, fields:, **)
161+
query.each do |record|
162+
record.update! user_id: fields[:user_id]
163+
end
164+
165+
succeed "Assigned the selected records."
166+
end
167+
end
168+
```
169+
170+
For a long list that needs search, use a [`tags` field with `fetch_values_from`](./fields/tags.html#fetch_values_from) in select mode:
171+
172+
```ruby
173+
# app/avo/actions/assign_user.rb
174+
def fields
175+
field :user_id,
176+
as: :tags,
177+
mode: :select,
178+
enforce_suggestions: true,
179+
fetch_values_from: "/avo/resources/users/action_options"
180+
end
181+
```
182+
183+
The endpoint receives the search text in `params[:q]` and returns objects with `value` and `label` keys. Both alternatives submit the selected ID as `fields[:user_id]`.
184+
144185
## Write the `handle` method
145186

146187
`handle` is where your business logic lives. It receives keyword arguments:

0 commit comments

Comments
 (0)