Read more

How to build the perfect number of blank records for a nested form

Henning Koch
July 06, 2011Software engineer at makandra GmbH

When you render a nested form for a Movie which has_many :actors, you want to render the right number of blank Actor forms. The right number means:

  • A minimum number of blank forms so the user can add more Actors to an existing Movie, e.g. 2.
  • A minimum total number of forms (both blank and pre-filled) so the user sees more than just 2 blank Actor forms when she is entering Actors for the first time, e.g. 5.
Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

For the example above, this is the desired progression of the number of blank forms:

Number of actors Number of blank actor forms
0 5
1 5
2 5
3 5
4 6
5 7
6 8

Luckily, there's an app for that. Copy the attached file to config/initializers to get a handy method build_nested_records:

- form_for @movie do |form|
  = form.text_field :title
  - form.build_nested_records(:actors)
  - form.fields_for :actors do |actor_form|
    = actor_form.text_field :name

Options

The build_nested_records helper takes an options hash like this:

form.build_nested_records(:actors, minimum: 7, buffer: 3)
  • The :minimum option is the minimum number of total records for which forms will be rendered. The default is 5.
  • The :buffer option is the minimum number of blank forms you want. The default is 2.
  • You can also give a :maximum option to limit the number of total rows. By default there is no limit.

You can also set defaults for built records by adding additional keys to the options hash:

form.build_nested_records(:actors, :minimum: 4, name: 'Foo', active: true)

If you want to call a different method rather than build, you can pass a block:

form.build_nested_records(:actors) { @record.my_custom_build_method }

Building has_one associations

When your Movie has_one :director, the initializer won't work because form.object.director is nil, if there's no director yet. Just use the default form.object.build_director. Generally spoken:

form.object.build_<attribute_name>
Henning Koch
July 06, 2011Software engineer at makandra GmbH
Posted by Henning Koch to makandra dev (2011-07-06 16:21)