247 Nested forms [2d]

Updated . Posted . Visible to the public.

Sometimes a form edits a record together with its child records, like a movie with its showtimes. This lesson covers Rails' nested attributes and how to build and test such forms.

Important

Work on this lesson in advisor mode.

Learning goals

  • You can explain how nested attributes let one form save a record together with its child records in a single transaction β€” all of it or nothing.
  • You can explain how Rails form helpers name nested inputs and how those names turn into the nested structure of params.
  • You can build a form that adds, edits and removes child records, ignores child forms that were left blank, and validates the rest.
  • You can add child forms in the browser without a page load, using a JavaScript component that copies a template and adjusts the input names.
  • You can write that JavaScript as a reusable component that knows nothing about a particular model.
  • You can test a nested form, including how to address repeated fields.
  • You can lay out a nested form so that child records are visually grouped and separated from the parent's fields.

Resources

Read what's new to you, skim what's familiar, skip what you already master. Stop when you can meet the learning goals.

Your agent can also generate an overview, a tutorial or an explanation for anything here, tailored to what you already know. Just ask.

Exercises

Showtimes for MovieDB

  • A movie has a list of showtimes. Each showtime consists of the name of the cinema, and the start datetime (both can be simple text fields).
  • Expand the movie form with a simple interface that allows adding, editing and removing of showtimes.
  • It is fine when you can only add 5 new showtimes at a time. Submitting the form will produce 5 new, blank showtime forms.
  • Showtimes should validate the presence of cinema and start. However, when the form for a showtime has a blank cinema and start, that form should be ignored and no validation errors should be shown.
  • Make sure to write tests for the showtimes form. How do you refer to the showtimes fields when there are multiple inputs for the date?
  • Inspect your nested form and observe the [name] attributes of your inputs. How does Rails assign the input data to the correct objects?
  • Style nested showtimes forms so showtimes are clearly separated from each other and from regular movie attributes. Avoid rendering a soup of text fields floating in an ocean of random margins.

Dynamic showtimes

Change the movie form so it no longer shows blank showtime fields for adding a new showtime. Instead there should be a button Add showtime that reveals a new blank showtime form.

The user can click on Add showtime as often as they like, always producing one more showtime form.

Implementation hint

  • Render a single blank showtime form.
  • A JavaScript component finds the blank form and hides it as a template for future showtimes.
  • Clicking on Add showtime will copy the hidden template element, adjust [name] and [id] attributes and append it to the DOM.

Component reuse

Package the Add showtime functionality as a generic JavaScript component so we can reuse it in other nested forms. For this to work the component must not contain any code or names specific to movies or the movie form.

Test that the component is reusable by allowing to add an actor's roles from within the actor form:

Name:     [Al Porciono     ]

ROLES:

+---------------------+-------------------------+------------+
| Movie               | Character               |            |
+---------------------+-------------------------+------------|
| [The God Father v ] | [Michael Corleone     ] | [ ] Remove |
| [Scarface       v ] | [Tony montana         ] | [ ] Remove |
| [Heat           v ] | [Vincent Hanna        ] | [ ] Remove |
|---------------------+-------------------------+------------+
| [Add role]                                                 |
+------------------------------------------------------------+

[ SAVE ]

Add a character (or casting) field to the Role model if you haven't already.

You do not need to implement authorization for the nested roles table. It is OK to create roles for any movie, even though you may not have write access to that movie.

Profile picture of Henning Koch
Henning Koch
Last edit
Michael LeimstΓ€dtner
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra Curriculum (2015-09-15 09:42)