Nested records when creating
A lot of you asked for the ability to create nested
has_many records on the
New view. Although it's fairly "easy" to implement using
accepts_nested_attributes_for for simple cases, it's a different story to extract it, make it available, and cover most edge cases for everyone. That's why Avo and no other similar gems dont't offer this feature as a first-party feature. But, that doesn't mean that it's impossible to implement it yourself. It's actually similar to how you'd implement it for your own app.
We prepared this scenario where a
Reviews. I know, it's not the
Items example, but you'll get the point.
Full set of changes
Guide to add it to your app
You can add this functionality using these steps.
accepts_nested_attributes_for on your parent model
class Fish < ApplicationRecord has_many :reviews, as: :reviewable accepts_nested_attributes_for :reviews end
Ensure you have the
has_many association on the parent model.
2. Add a JS helper package that dynamically adds more review forms
yarn add stimulus-rails-nested-form
In your JS file register the controller.
3. Generate a new resource tool
bin/rails generate avo:resource_tool nested_fish_reviews
This will generate two files. The
NestedFishReviews ruby file you'll register on the
FishResource file and we'll edit the template to contain our fields.
4. Register the tool on the resource
We'll display it only on the
class FishResource < Avo::BaseResource # other fields actions, filters and more field :reviews, as: :has_many tool NestedFishReviews, only_on: :new end
5. Create a partial for one new review
This partial will have the fields for one new review which we'll add more on the page.
<!-- app/views/avo/partials/_fish_review.html.erb --> <%= render Avo::PanelComponent.new do |c| %> <% c.with_body do %> <div class="nested-form-wrapper divide-y" data-new-record="<%= f.object.new_record? %>"> <%= avo_edit_field :body, as: :trix, form: f, help: "What should the review say", required: true %> <%= avo_edit_field :user, as: :belongs_to, form: f, help: "Who created the review", required: true %> </div> <% end %> <% end %>
6. Update the resource tool partial
It's time to put it all together. In the resource tool partial we're wrapping the whole thing with the
nested-form controller div, creating a new
form helper to reference the nested fields with
form.fields_for and wrapping the "new" template so we can use replicate it using the
nested-form package. In the footer we'll also add the button that will add new reviews on the page.
7. Permit the new nested params
There's one more step we need to do and that's to whitelist the new
reviews_attributes params to be passed to the model.
class FishResource < Avo::BaseResource self.extra_params = [reviews_attributes: [:body, :user_id]] # other fields actions, filters and more field :reviews, as: :has_many tool NestedFishReviews, only_on: :new end
There you have it!
Apart from the resource tool and the
extra_params attribute, we wrote regular Rails code that we would have to write to get this functionality in our app.