DEV Community

Katherine Kelly
Katherine Kelly

Posted on • Edited on

Why Yes, I’ll Accept Those Nested Attributes

Building forms in Rails has been a fun exercise of demystifying what happens behind the scenes on your favorite sites. Those fun quizzes you’ve answered and comments left on a blog post are being collected by companies and saved to a database, to be used for whatever purposes later on. Good times.

Forms can be simple endeavors, such as a generic search form or a form to update your account profile page. But oftentimes, forms are complex where you may need to update more than a single object at a time.

Let’s say you have a form that allows you to create a trainer and its new Pokemon at the same time.

pokemon gif

With Active Record, it simplifies this process by allowing you to save attributes on associated records through the parent model using the accepts_nested_attributes_for class method. In a one-to-many relationship, the accepts_nested_attributes_for method always lives on the parent/has_many model.

By default, nested attribute updating is turned off so you will have to enable it using accepts_nested_attributes_for. By using this Active Record macro, it will add a new writer method to your model that will be named after the association.

 pokemons_attributes=(attributes)
Enter fullscreen mode Exit fullscreen mode

Your trainer model should reflect the has_many Pokemons relationship.

 Class Trainer < ActiveRecord::Base
     has_many :pokemons
     accepts_nested_attributes_for :pokemons
 end
Enter fullscreen mode Exit fullscreen mode

Your controller should be updated to declare the permitted parameters before you pass the parameters to the model.

As for when you might need to write a custom association writer method, #accepts_nested_attributes_for is not able to help us avoid duplicates. For the purposes of this exercise, a trainer can only have one Pokemon of the same name, just like the Pokemon universe hero Ash Ketchum.

Our custom method, which will be written in the trainer model, will use the Active Record query method find_or_create_by to look to see if that Pokemon already exists in the database, and if not, will instantiate that Pokemon for us and associate it to our trainer by adding it to the trainer’s Pokemon collection.

An important thing to note is that accepts_nested_attributes_for and custom setter methods are not necessarily mutually exclusive. You will have to evaluate the needs of your specific use case and go with the approach that makes the most sense for your application.

Active Record Nested Attributes
Basic Nested Forms

Top comments (3)

Collapse
 
therealrodk profile image
therealrodk

Thanks for this! It is a cute example, easy to follow, and helped us work out an issue we were having with our own dynamic forms!

Collapse
 
aggyk profile image
Agnes Selvita

Exactly the example I was looking for, thanks! :)

Collapse
 
linqueta profile image
Lincoln Rodrigues

Thanks for this too, you helped me in a test!