Dynamically Create Objects With Plain Ruby on Rails. (No Javascript)

turpp

Thomas(Tripp) White

Posted on December 31, 2020

Dynamically Create Objects With Plain Ruby on Rails. (No Javascript)

I just finished building out Tournament Wizard. This application is designed to help with running golf tournaments. Last year I took over the tournament chairman position at my golf course. My responsibilities are planning and running golf tournaments for the the club. I found out the hard way, running a golf tournament is stressful. The way the club had done it for years was just with old fashion pen and paper. Being a developer this drove me crazy. That lead me to the creation of Tournament Wizard!

Alt text of image

The Problem

Just to give you an idea of how my club runs tournaments. They have a signup sheet in the clubhouse. Golfers signup for the tournament and then on tournament morning, the club gives the me list and says here you go, get everyone checked in. I need a way to add teams and golfers to the application quickly. The standard way of using a form to create one object at a time would be too tedious. I needed a way I could create as many objects as I need on the same form.

Adding Multiple Objects

Rails forms are fantastic. It gives the user a lot of power to make simple forms fast and easy. Unfortunately, I need to do something with my forms that normal rails magic wouldn’t do for me. I wanted a way I could dynamically add teams to the tournament. The standard way of creating objects with rails is with FormBuilder. There are different ways to use FormBuilder but, the two main types I use on a daily basis is form_for and form_tag. Form_for uses the most rails magic. You simply tell the form what object the form is for and it takes care of the rest. The problem with form_for, for my problem, is that it creates a form for a single object. If I called the same form multiple times in my view it would just remember the input for the one object. I can’t be dynamic with form_for. That is why I had to use form_tag. Form_tag takes away some of the rails magic and gives me more control over the form. The main reason why form_tag allowed me to be dynamic is because I can state how I want my params to be stored and passed to the controller. Form_for uses rails magic and assigns it to a single object. With form_tag I can take the input from the user and store it in a custom params that contains an array of all the user input. Once its in this array, I can iterate over that array in my controller and create all the objects.

The solution

So how does all this look. Lets dive into the code.

First

I needed to get from the user how many objects they would like to create. I did this with a simple form that just ask for a number. On submit it takes the number and in the controller it redirects to the new action of the appropriate controller. I created a custom route for my new actions to include the number in my url. This allows me to pull that information in my new action and use it in my view.
Alt Text
Alt Text

Second

I created a form using form_tag and defined the type of form and where to send the information once submitted. I also created a partial. A partial is a view that you can call from within a view. Its a great way to DRY your code. I used this partial for a different reason, to be dynamic. My partial is basically the guts of my form_tag.(All the labels and input tags needed to create an object.) In my partial, I was very careful how I named the input tags. I need to make sure that no matter how many times I called on this partial it would store the inputs in groups for each object. I did this by storing the inputs from each partial as an element in an array. You can do this by making sure there are brackets in the name section on the input tags. For example in my players partial: <%=text_field_tag "player[][name]",@player.name%>. The [ ] after players tells rails to store the information in an array. So if I called the partial twice the params would be and array with two elements, each element being the information from that specific partial.

Alt Text

Third

Remember how I created a custom route for my new action. The user enters how many objects they want to create. I take the number from the custom route and assign it to a variable. In my view I just call my partial the number of times the user requested with <% @n.times do%>. Since I am just calling this on the partial the user sees multiple fields to fill out but only one submit button.

Alt Text

Fourth

Once they fill out the fields and submit the form, the params is stored in an array. In my controller all I have to do now is iterate over that array and create my objects just like I would if it was a normal 'form_tag' for a single object.

Alt Text

This is a huge time saver for the user. It allows them to quickly create multiple objects. This is all done with out javascript so it is very quick to implement. I encourage anyone out there thats not comfortable with javascript but wants to dynamically create objects to try this method. It really took my application to the next level!

💖 💪 🙅 🚩
turpp
Thomas(Tripp) White

Posted on December 31, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related