Wednesday, 15 February 2017

Applied Rails : Variable Rows For Child Records

I got a requirement in my Rails application to give the user the ability to input a variable number of records with multiple fields. The fields were of text type as well as select comboboxes. These rows had to be saved to the database as child table rows.

As is my inclination, I sought out to code it in raw HTML / JavaScript. Of course, I did google for readily available solutions, found some but ruled them out for different reasons. First step was to write a HTML file to achieve the desired functionality.

The first column in the table has a check box, the second column displays the row number and the remaining columns have other attributes. Below the table there are two buttons, one to add a row and another to delete a checked row. Each invokes a JavaScript function when clicked.

The function to add a row, addScreenRow takes the table id as an argument. It takes the current row count of the table and increments by one to display for the new record. It inserts a new row with a call to insertRow and add child elements to the cells.

Similarly, the function to delete a row, deleteScreenRow takes a table id as argument. First it gets the current row count of the table. It then loops through the rows, and if the checkbox is checked, it calls deleteRow on that row.

The following html file illustrates the code and usage of these JavaScript functions. We now tackle the latter part of the requirement. Our dynamic rows need to have comboboxes, which as given in Wikipedia are "a combination of a drop-down list or list box and a single-line editable textbox, allowing the user to either type a value directly or select a value from the list." To go with the spirit of my approach, I did not use library widgets.

I found a very nice solution on question 264640, in the answer given by Max. It is simplicity exemplified, where we get the combobox feature with a few lines of CSS and one line of JavaScript. The code is also available on fiddle.

Plugging this into my HTML was quite easy. In the JavaScript, instead of just a text element, we need to add a div with a text element as well as a select element into the cell. That's it. Now on to the main task of providing this feature in a Rails app. Let's consider an order entry screen. Our models are Order and LineItem.

An Order has many LineItems and a LineItem has item, quantity and gift wrap type as attributes. User enters item as text, quantity as a number and for the gift wrap type, can either select one of the dropdown values provided or enter a string as its value. The one to many relationship between Order and LineItem is expressed with has_many and belongs_to keywords in the model classes and with the foreign key in the database table.

Code for achieving this is straightforward Rails:
class Order < ActiveRecord::Base
    has_many :line_items
    accepts_nested_attributes_for :line_items, allow_destroy: true
class LineItem < ActiveRecord::Base
    belongs_to :order
migration file
def change
  add_reference   :line_items, :order, index: true
  add_foreign_key :line_items, :orders
We make one key change from the basic HTML form that we saw above. The variables for each field have to be given the name of the database column. Rails will take care of doing the insert.

The child records are nested attributes in the view, and are sent as hashes inside arrays of hashes. So the naming has to be done as shown below, inside backticks for JavaScript to evaluate the global row count variable = `order[line_items_attributes][${globalLineItemsRowCount-1}][quantity]`;
For the update operation, we will go with a different form, _edit_form. We render it as a partial in the edit view file. This form is same as _form with a couple of changes.

We use a variable to display the row number in the second column of the html table. We initialize its value to 1 and increment for each row. In the JavaScript part, we initialize the global row count to one more than the number of child records.
var globalLineItemsRowCount = <%= @order.line_items.length+1 %>;
<% counter = 1 %>
<%= f.fields_for :line_items do |l| %>
        <td><input type="checkbox" name="chk"/></td>
        <td> <%= counter %> 
        <% counter += 1 %>
The next thing to take care of is the delete operations for the child rows. This occurs when the user deletes the rows from the edit screen. We do something extra for this in the update action.

For deleted rows, the form parameters for the child rows will have only one member which is the id of the child record. So we check if a particular attribute parameter is of size one and has a 'id' value. If yes, we delete the child record by calling destroy.
if order_params[:line_items_attributes] != nil
   order_params[:line_items_attributes].each do |la|
      if la[1].length == 1 && la[1]['id'] != nil
I have made a small project and put it on github. It's called mahrasa, short for Mahboob Rails Sample. Check out the code from, to see more details that I could not accommodate in this article, play with it and let me know your feedback.

Wednesday, 11 January 2017

Welcome 2017

First blog post at the beginning of the year, as was last year's, is a quantified compilation of my personal activities outside of my day job.

Sunday, 6 November 2016

Book Review : Everyone Has A Story

The novel 'Everyone Has a Story' by Savi Sharma is structured on the classic three acts of a romantic story: lady meets man, man goes away from lady and lady gets man back. Lady's goal is to become a writer.
It was a breezy read for me and appealed to me as a record of the good-heartedness in people.

Friday, 21 October 2016

Steps And Commands For RoR Application Deployment On Linode Server

I deployed my Ruby-on-Rails application on a cloud server.

About a couple of years ago, I got into this practice of hosting my applications on the cloud. At that time AWS did not offer Ubuntu machines. I love Ubuntu so I did not go to AWS. I also have this feeling that access and deployment procedures on the biggies (AWS and Azure) are slightly more cumbersome than the not-so-biggies. Amongst these, Site5 is the cheapest but I don't get root access and was very disappointed with their lack of support. For $20 a month, I got a 4 GB RAM server on Linode compared to 2 GB RAM on Digital Ocean. Hence I went with Linode.

Friday, 8 April 2016

Practical Rails : Adding a bootstrap theme

When you are trying to get your webapp prototype or MVP up and running, you wouldn't wait for your UI group to deliver their entire UI assets. {wrap}bootstrap is a good place to get bootstrap themes for less than $20. And who knows, the theme you select maybe good enough to go to production.

In this post, I present the steps to plug a bootstrap theme into your Rails app.

Friday, 1 April 2016

Hello World : Virgin Identifier

On behalf of the Hyderabad Machine-language Engineers Network (HYMEN), I am extremely happy to announce that we have come out with a technology solution to identify whether a girl is a virgin or not. The name of our product is VirIde (pronounced We Ride), short for Virgin Identifier. It can be applied in a very discreet and non-intrusive way, and solves a huge problem burdening our society.

It has been a very natural law through out human evolution that males have always wanted uninhibited fun in their pre-marital age, but display obsessive preference to virgins when they want to marry. How can one know whether a girl is virgin or not? There is no way to find out this fact without violating the legal, ethical, and probity standards of our age.

Friday, 8 January 2016

A Ruby Program On Logistic Regression

I wrote, rather translated, a small program in Ruby on logistic regression. There is a github repository "python-ML-minimal" that has programs written for Prof. Andrew Ng's machine learning class assignments. The cool thing is they are written with only the core language features without any dependency on libraries.