Goals
- Understand how nested attributes appear in the params.
- See how the Rails form helpers encode the names of nested inputs.
- Understand how the record and all of its nested attributes are saved in a transaction. That means the entire structure is saved or not.
Resources
- Rails Guide: Nested forms Show archive.org snapshot
- Nested Forms in Rails Show archive.org snapshot
- Popular mistakes when using nested forms
- When aggregating nested children, always exclude children marked for destruction
- Unpoly + Nested attributes in Rails: A short overview of different approaches
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 ]
Birthday: [1940-04-25 ]
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 birthday
field to the Actor model and a character
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.