Nested Form in Ruby on Rails

Image for post
Image for post
Logo of our “Slang Translate”

Yes, again! I’m here to “brag” about my group project “ SlangTrans!”. The idea is to make a web application like wikipedia, where people could create new slangs and others could help to translate it into other languages. Since my teammate Fanzhong Zeng and I have limited language proficiency, we decided to limit language-options to: English, Mandarin and German.

As always, before we code, we planned our classes relationships as below:

Image for post
Image for post
Relationships of Classes in SlangTrans

After user signs in, user is able to create, edit, and delete a slang with definitions in different languages, and user could also relate books according to the slang. As guests, who don’t sign-up or log-in, they are only able to read the slangs, because of the authorization and authentication. It is basic and there are still more features we could add, but due to three-day-preparation, we limited our project content.

The most challenging part for me during our project, is nested form. Yes, that sounds-simple-but-a-lot-of-work-form. I’ll use Definitions belongs_to Slang relationship to explain how I accomplish it.

With creating a slang, definitions would also be created and saved in the database with the specific slang-id as shown in the following GIF.

Create Form Page Demonstration
Create Form Page Demonstration
Nested Form App Demonstration

Let’s start from the scratch.

Migration → Models → Controllers → Views

Migration

Because definitions belongs to slang, and we need to use Definition attributes in Slang, definition should have references instead of belongs_to to the Slang, where we have slang-id for definition. This will create a schema.rb as followed.

Source:https://gist.github.com/GAierken/b7ca51684115705fa4da75263c336a00
Image for post
Image for post
Source: https://gist.github.com/GAierken/05c215f8db23a68f56b03a27440878bf

Models

After migration, we need to make sure the relationship between slang and definition is also established in Slang model.

Source:https://gist.github.com/GAierken/2395c05fc971cd4e2197484ffaf36df7

In Slang.rb, we used “accepts_nested_attributes_for :definitions, to make sure that user can submit attributes for new Definition instances in a form_for a Slang. You might wonder what “reject_if” is. Rejecting blank fields will ensure that Rails does not create a new Definition if any field of Definition is blank. We set a “:reject_if proc” to silently ignore any new record hashes if they fail to pass our criteria. Persistence is everything!

Image for post
Image for post
Blank Field Demonstration

How about Definition.rb? “references :slang” is created during migration. No other “trick” needed.

Source:https://gist.github.com/GAierken/7ba277a34829abf98d11509ef85830b4

Controller

Migrations and models are set. Now the controller. Due to the form is in view/slangs/new, we need to create definition in slangs_controller.

Image for post
Image for post
Source:https://gist.github.com/GAierken/2f65d1d6ba662af5d847df0f4b608ef7

Since we chose three different languages, and the creating form would show three fields for definitions, that’s why I did 3.times @slang.definitions.build. The “:id” is to make sure you do not end up with a whole lot of tasks. The “:_destroy”must be there so that we can delete tasks.

Views

Now to views/slangs/new.erb file part.

Image for post
Image for post
Source:https://gist.github.com/GAierken/1f663260f9b3867e758cc9e3fba1047e

“f.fields_for” in form_for connected Slang and Definition. Correct migration, proper model-set, precise controller content make sure that the submission of this form would work as intended.

After all this done, our web application is able to do the creation as I shown in the previous GIF.

As an old saying: all Roads Lead to Rome, there must be a better way!

Smart and “lazy” developers created so many ways to nest a form. There are new gems that would make nested-form even easier. Like our dear friend Jakarai Forsythe recommended in his blog. Simple form gem.

And nested_form_fields gem.

Now as I’m learning JavaScript. I bet there would be even more “tricky” nested-forms. I’ll learn as I go, hopefully would find even easier and more convenient way to solve this “mystery”.

References:

Written by

Multi-human-lingual and multi-programming-lingual | https://www.gaierken.com/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store