Multiple models in a single form

Following on from our form containing diverse controls, let’s look at how to update multiple models from a single form.

Rails has a concept of “nested” models, generally represented by has_many relationships. As we’ve been dealing with people, let’s give our person multiple addresses:

The first bit is simple enough, the second bit tells the model to accept parameters for its addresses whenever you are updating this model.

Our form can then look like this:

The fields_for declaration goes through all the addresses associated with that person and adds in the fields shown, once per address. It also mangles the name and ID properties so that if the form is submitted, the accepts_nested_attributes_for call in our model can step in and assign the field values to the correct addresses.

However when we view this form for a person, we’ll notice that there’s no addresses to be shown – and we can’t add a new one. The way round that is to add a dummy address to the collection and let Rails save it if you fill it in. The controller is the place to do this, getting stuff ready before it’s rendered as a view.

This adds a blank address to the end of the list. If we fill it in, Rails will add it into the addresses table, if it’s all blank, then it will be ignored (as we specified reject_if :all_blank in our model).

What about removing an address?

Again, Rails has a bit of magic to help us out. If we add the following to our form:

We check if the address has already been saved to the database (there’s no point deleting a brand new address that hasn’t been persisted yet) – and if it has, we add in a new checkbox for a fake field _destroy. If this is ticked, when the form is submitted, our model intercepts it and deletes those addresses.

So there you have it – one of the most important bits of your average Rails app, made easy.

Do you know what to do but not how it works?

Ever wanted to understand why Rails views work the way that they do? Why variables from your controllers are visible inside your views?

Sign up below to get a free 5 part email course on how Ruby on Rails view rendering works and gain a deep understanding of the Rails magic.

We will send you the course, plus the occasional update from this web-site. But no spam, we promise, and it's easy to unsubscribe