Rails — Nested Forms and Nested Resources

I just completed my first full Ruby on Rails app for my third project in Flatiron School’s Software Engineering Bootcamp. One of the requirements for this project was to include at least one nested resource within the app. In this way a model would be directly associated with its parent model upon instantiation without having to use a nested form.

I decided to create an app where users could recommend different online media to each other. I was working with three different models: users, recommendations, and media_assets. The recommendations resource was nested under the users resource since the recommendations would belong to a user, and a user would have many recommendations.

Setting Everything Up

Setting up the nested resource itself is easy enough you simply have to create a block in the routes.rb file like so:

This creates paths so that the controller can use those actions to associate with a particular user.

I took things a step further though. A recommendation not only needed to be associated with a user, but also needed to be associated with a media_asset because the whole point of the recommendation is that you’re telling someone about a piece of media. This meant I needed to include a nested form to include being able to create a media_asset with the creation of the recommendation itself.

The form included two options: selecting a piece of media from the database, or creating your own.

I included accepts_nested_attributes_for in the recommendations model since I was using a nested form.

I added the media_asset_attributes to my params in the recommendations controller.

I made sure to check for a user_id in the params (identifying this as a nested resource route) in the create action of my recommendations controller, and then build the new recommendation properly:

I thought that I also needed a custom writer for the media_asset_attributes in the recommendations model to handle a find_or_create_by since that was an option in the form:

Running Into Issues and Debugging

What I didn’t realize was that regardless of whether or not the user was completing the nested part of the form, the accepts_nested_attributes_for and the custom writer were both firing. This was causing recommendations to be instantiated with the same media_asset no matter which one the user had chosen.

After much debugging it was finally realized that that was in fact the issue and I didn’t need the custom writer to achieve what I needed. I just updated the accepts_nested_attributes_for:

So that now it wouldn’t run if the nested portion of the form was left blank.

Then I added a validation to the media_asset model to ensure there wouldn’t be any duplicates in the database:

Not only were recommendations now being instantiated correctly, but the code was cleaner and dryer.

Bringing It All Together

Being able to associate models together in dynamic and effective ways is really the basis for a powerful webapp. Rails makes this easy to achieve if you set things up in the right way. Nesting resources, and using nested forms allows for seamless interactions within your app, and gives a lot of flexibility when it comes to whatever functionalities you may be trying to achieve.