Forms within forms within forms

Natasha Gitlin
Aug 8, 2017 · 3 min read

After completing my 2nd rails app, I feel so much more confident in nested forms/attributes and Rails, in general. It took me some time to figure out when and how the JOIN table was being used and where I should be adding my custom methods. I’m going to go through some steps that I struggled with in my project regarding the nested forms. I created a Recipe App with ingredients nested within the recipe form. First thing I tackled was associations with a has_many, has_many, through: and belongs_to relationships where I filled them out in the model files.

  1. Recipes, Ingredients and the JOIN table, recipe_ingredients.
  2. Recipe: has_many ingredients, through: recipe_ingredients and has_many: recipe_ingredients. Also, belongs_to a User.
  3. Ingredient: has_many recipes, through: recipe_ingredients and has_many: recipe_ingredients.
  4. Recipe_Ingredients: belongs_to both a Recipe and Ingredient.

After building the associations, migrating my database table and adding in my MVC model with the essentials of the Recipe Form, I dove right into the nested form.

ActiveRecord has a built-in method that you may add into the model form:

However, to get an even better understanding of what this method does exactly is writing a custom method within the same Recipe.rb model called Ingredient_Attributes= (in Ruby, it would be like adding in a custom writer/setter method instead of using attr_accessor). This way, you’re able to customize it instead of using ActiveRecord validations (which I haven’t been comfortable enough with yet)

What this does is creates a nested attributes hash within the Recipe model so when you check in on the parameters of Recipe, you will see if the ingredient name is saved or updated and if it is added into the hash. I built strong parameters called recipe_params, where the code you are inputing in the form is explicitly telling the model the parameters. Here is what it would look like from the Recipe_controller and how it translates to a key/value hash.

Strong Params

To reach the name in ingredients_attributes would look something like: name = ‘recipe[ingredients_attributes][]’.

This is only to give a visual of what the nested params looks like. It is not necessary to be used in your application files. You can look up your hash by adding in ‘raise params.inspect’ in your create or show controller method.

After this is all worked out, you just need to add it to your view _form.html.erb. Rails has built-in form helpers called fields_for as well as a ruby gem I used called simple forms.

Simple_forms is a built in ruby gem that allows you to more easily adjust what your form will look like visually and integrates with bootstrap.

A great nested forms lecture that helped me tremendously when figuring this all out. He works through it without all the form helpers and shortcuts so you can get a sense of how Rails is working the magic.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade