Friday, 11 August 2017

I Dare You Not To Fall In Love

On the best part of using Ruby on Rails for software development, thus spake its creator David Hansson:
You get to use Ruby, which, even in a world that has rediscovered the benefits of functional programming and immutability, remains the most extraordinarily beautiful and luxurious language I’ve yet to encounter. Just look at some code. I dare you not to fall in love.[1]
Well, this is my exact opinion of Ruby, my most favourite programming language but I couldn't have articulated it any better than Hansson.

Beauty, simplicity and aesthetics were not the main considerations in choosing Rails for my current project. I am part of a SMB that's into industrial manufacturing and services, in which the IT department is even smaller. So, strictly speaking, though I don't work in a startup, I work in a startup mode.

During the course of discussions on building a web application, I got a poser: can you make it at the lowest cost possible? My salary is a sunk cost, so the lowest marginal cost would be zero by developing the application myself. My incoming skill set when I joined the company was Java and Meteor, which was what the management knew. I said, yes I can, but the technology will be Ruby on Rails. Which technology I use was not a concern of the business so long as the application worked and was reasonably performant.


A full-stack programmer needs a full-stack framework, or a near-full stack framework. Meteor comes with MongoDb under the hood, so it's a full-stack framework whereas Rails does not come with a built-in database, so it's a near-full-stack framework. But if we leave the database part out, as Hansson stated, "Rails is full-stack by default. We have a pragmatic, full-stack answer that could be formulated based on that ideology that still offers amazing productivity from the second you run the rails new command."[1].

Thus I switched from a person who used to split time 80% - 20% between supervision and coding to the exact reverse: 80% of the time on software development and 20% of the time on management. I ploughed on as a full stack developer hitting at the keyboard for most part of the day, with me in the avatar of requirements gatherer, coder and tester all rolled into one. A person with 25 years experience and coding may be a rarity in my city, but I am not alone in the world.[2]

The application, an employee and customer engagement portal, is live and it could not have happened without Rails. The functionality I put in is: security layer with encrypted passwords, forgot password, role based access, authority based email notifications for approvals, paginated views, dynamically growing tables, pdf / Excel documents, bulk-emails, file uploads / downloads — all around the business logic, departmental workflows and management reports.

Along the way, I captured my learnings in applying Rails and shared them on my blog; these posts were re-published by DZone:
Title Blog Link DZone Link
Practical Rails : Adding a bootstrap theme http://mh-journal.blogspot.in/2016/04/practical-rails-adding-bootstrap-theme.html https://dzone.com/articles/practical-rails-adding-a-bootstrap-theme
Steps And Commands For RoR Application Deployment On Linode Server http://mh-journal.blogspot.in/2016/10/steps-and-commands-for-ror-application.html https://dzone.com/articles/steps-and-commands-for-ror-application-deployment
Applied Rails : Variable Rows For Child Records http://mh-journal.blogspot.in/2017/02/applied-rails-variable-rows-for-child.html https://dzone.com/articles/applied-rails-variable-rows-for-child-records
Applied Rails : Customizable Text http://mh-journal.blogspot.in/2017/03/applied-rails-customizable-text.html https://dzone.com/articles/applied-rails-customizable-text
Applied Rails: Bulleted Text With Prawn http://mh-journal.blogspot.in/2017/03/applied-rails-bulleted-text-with-prawn.html https://dzone.com/articles/applied-rails-bulleted-text-with-prawn
Applied Rails: An Algorithmic Perspective http://mh-journal.blogspot.in/2017/04/applied-rails-algorithmic-perspective.html https://dzone.com/articles/applied-rails-an-algorithmic-perspective
Applied Rails: Gems I use http://mh-journal.blogspot.in/2017/06/applied-rails-gems-i-use.html https://dzone.com/articles/applied-rails-gems-i-use


If working with Ruby is the best part of using Rails, the second best part is the Ruby community. Remember, I had no architects and software engineers in my team. Online articles and forums were my only recourse if I got stuck. I always found helpful tutorials or answers to my questions. There is a certain down-to-earth and friendly attitude that I felt from the Ruby community.

No wonder the community has a value system that takes forward the full ideology of Rails enunciated in the nine pillars of The Rails Doctrine[3]:
  1. Optimize for programmer happiness
  2. Convention over Configuration
  3. The menu is omakase
  4. No one paradigm
  5. Exalt beautiful code
  6. Provide sharp knives
  7. Value integrated systems
  8. Progress over stability
  9. Push up a big tent
Alhough the bulk of my career was with large applications and teams, over the last three years, I have worked with companies and projects that can be described as startups / startup mode / small-team companies. When some asks my opinion on technology choice, I suggest as a first cut:
Stage Framework Language
Startups, mobile device focus or build MVP to get funding Meteor JavaScript
Startups without mobile device focus or early stage companies Rails Ruby
Funded projects Spring and Hibernate Java
Established companies with massive scale Polyglot Programming Java coexisting with Scala, Node.js, Python

When I look back I feel satisfied at what I could deliver. Based on my experience, it seems to me that the third row in the above table can be eliminated and the stage merged with the second. That is, enterprise application development should happen in Rails rather than Java, notwithstanding the immense appeal of Spring Boot. Of course, this is my opinion based on my experience and influenced by the local ecosystem. One thing I can say emphatically is that Rails brings high productivity with small teams, in other words, lower costs.


References:
[1] https://www.quora.com/What-makes-Rails-a-framework-worth-learning-in-2017/answer/David-Heinemeier-Hansson
[2] https://belitsoft.com/php-development-services/top-software-developers-after-40-50-and-60
[3] http://rubyonrails.org/doctrine/

Friday, 2 June 2017

Applied Rails : Gems I Use

In this article, I discuss key gems that I have used in my Rails application. For each gem, I state what it is used for, a brief description of how I used it and the code snippet(s) pertaining to my use case.

devise
I use the devise gem for user authentication. It has 10 modules: Database Authenticatable, Omniauthable, Confirmable, Recoverable, Registerable, Rememberable, Trackable, Timeoutable, Validatable, and Lockable. The cool thing is you can use only the modules that you want.

cancan
I use the cancan gem for user authorization. All I had to do was run a simple command and override the initialize method in the User class.
In the following code snippet, users in role commercial_officer are allowed to execute the claimsForChecking action in the ExpensesClaim class. A caveat: cancan is no longer supported, and if you are starting afresh, you got to use cancancan.

role_model
I use the role_model gem to provide role based access. The cool thing about it is that you can control the roles by just altering a number in the database table. Let's say you have six roles: guest, executive, manager, sales, cxo, admin. Since it works on bit mask, each of the role gets the value of 2n where n ranges 0 to total number of roles minus 1. In the six roles I mentioned, guest gets 1 and admin gets 32. So if a CXO also has a sales role, give her record's roles_mask column a value of 8 + 16 = 24 in the database.

In the following code snippet, a user is given their role at the time of user creation. The set_roles_mask method takes the email used for registration, checks if the email is present in the Employees master table and if yes, sets the Users table roles_mask to the value in the Employees table. If the user is not an employee the user is given a roles_mask of 1 (guest). The checking code in the UI layer looks like the following code; here only some users (either in the CXO role or those in the Bulk_email_team) are given access to a particular menu item in the navigation bar. With the combination of devise, cancan and role_model you will have a robust production-ready security layer for your application, all with a few lines of code. Java developers who use Spring frameworks will be surprised at the level of functionality that we achieve with a few lines of code in Rails. This, despite Spring Boot.

prawn
I use the prawn gem for generating pdf documents. It provides most of the features I require. For bulleted text with proper alignment, I had to write a small function that prints asterisks in the first column. See an earlier blog post of mine[1] post for more details.

prawn-table
I use the prawn-table gem for displaying content in tables inside pdf documents.
In the following code snippet, I check whether there is enough space on the page to render the table. If not, I display the table on a new page. fiscali
I use the fiscali gem for date calculations based on fiscal year.

In the following code snippet, first the time zone is set to India. If the user did not enter a starting date, the beginning of the Indian financial year (1st April) is taken. If the user did not enter a end date, today's date is taken as the end date. Using the two dates, records created in the table between the start date and end date are fetched.

config/initializers/fiscali.rb Code in controller date_validator
Data entered by users in the browser screens (HTML forms) is validated in the model classes. the date_validator gem eases the validation of date rules.

In the following code snippet, I validate that a travel record should be in the past or on today. First I check that there is an end date, it is after or on the start date and it is today or before. The start date has to be in the past or on today. But the nice trick here is, there is no validation code for the travel start date because the two validation rules of the end date automatically take care of it. The Rails data validation approach is explained as: "Nothing to do with our application comes out of the database or gets stored into the database that doesn't get first go through the model. This makes models and ideal place to put validations: it doesn't matter whether the data comes from a form or from some programmatic manipulation in our application. If a model checks it before writing to the database, then the database will be protected from bad data."[2]

wice_grid
I use the wice_grid gem to filter tabular data. You can also sort the data.

The following code snippet displays Offers in a wice grid and allows user to filter on the customer name. It even pulls the associated records from the customer and employee tables. The simplicity of Rails is evident in the link_to 'view or edit' the offer entity. paperclip
I use paperclip gem for attaching uploaded files to a particular entity. The use cases I have tackled using this gem are: 1) Allow the user too select from a pre-loaded set of documents. 2) Allow the user to upload any random file. Code snippets for these use cases are given below: Kaminari
I use the Kaminari gem when I have to display paginated data.

The following code snippet shows employee records in a paginated HTML table. axlsx_rails
I use the axlsx_rails gem to generate Microsoft Excel files. The following code snippet generates a xlsx file of customer, their location and contacts at each location. The header row having cells with blue fill. custom_error_message
I use the custom_error_message gem for customizing my error message not to have the attribute name prefixed.

This plugin uses the carat (^) to omit the name of the attribute from error messages. Here's an example: select2-rails
I use the select2-rails gem for selecting entries in ajax style from a drop-down. The following code shows how users select employee email ids from a select drop down and they get shortened list with each letter they enter. The extraordinary simplicity of Ruby and the amazing functionality offered by its gems make working with Ruby on Rails a pleasure. To quote David Hansson, the creator of Ruby on Rails[3]:
...two basic tenets of Rails appeal in 2017: 1) We have a unique ideological foundation that’s still controversial today and offers the same benefits against the mainstream choices as it did 13 years ago, 2) We have a pragmatic, full-stack answer that could be formulated based on that ideology that still offers amazing productivity from the second you run the rails new command.
Oh, and on top of all that, I’ve saved the cherry for last. You get to use Ruby, which, even in a world that has rediscovered the benefits of functional programming and immutability, remains the most extraordinarily beautiful and luxurious language I’ve yet to encounter. Just look at some code. I dare you not to fall in love.
References:
[1] http://mh-journal.blogspot.in/2017/03/applied-rails-bulleted-text-with-prawn.html
[2] Agile Web Development with Rails4 by Sam Ruby, Dave Thomas, David Heinemeier Hansson. 2013, The Pragmatic Programmers, LLC.
[3] https://www.quora.com/What-makes-Rails-a-framework-worth-learning-in-2017

Friday, 12 May 2017

Book Review : The Rise Of The Robots

The technology world faces new trends frequently. New technologies typically promise to get things done faster, reduce costs, and open new market segments, thus improving the financials of a lot of firms. From Service-oriented Architecture to mobile and cloud computing, all of them stake their claim to deliver these benefits.

However, the advent of Artificial Intelligence (AI) will impact the world economy in a way that no technology in the past was able to. This is the core thesis of Martin Ford’s 2015 book, 'The Rise of the Robots', sub-titled 'Technology and the Threat of Mass Unemployment.' If AI can unleash a tsunami of unemployment, how should America deal with it?

Friday, 14 April 2017

Applied Rails: An Algorithmic Perspective

The Human Resources manager informed that employees working in the corporate headquarters (CHQ) will have the second and fourth Saturday of the month off. This affected the leave balance calculation method in my Rails application. If a CHQ employee applies for leave and a second or fourth Saturday falls in between the start date and end date, they should not be deducted a leave.

I was already using the Rails date library. Given a date, I could get the beginning of the month and end of the month in which the date occurred. Before I could figure out how to proceed with this info, I went to stackoverflow.com and put up a question[1].

Friday, 17 March 2017

Applied Rails: Bulleted Text With Prawn

I use the prawn gem to generate pdf documents in my Rails application. It has a drawback that it does not have built-in support for displaying bulleted text. So I wrote a simple function that took a string parameter and printed it with an indent and a leading asterisk.

Friday, 3 March 2017

Applied Rails : Customizable Text

I got a requirement in my Rails application in which the user would add a set of "Terms & Conditions" in the Offer screen. These are typically standard, but the user should be able to customize the individual clauses. It sounded oxymoronic, but remembering Scott Meyers' words, "pretty this ain’t, but sometimes a programmer’s just gotta do what a programmer’s gotta do," I set out in right earnest to figure out what can be done.

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.

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.