Tools to track customers data

What are these tools and what do they do?

Recently I got a chance to work with different tools to track the customers data on your web app. I decided to use Intercom and Mixpanel.  Both these tools allow you to track customers activity in the form of an ‘event‘.

Events are basically activity a user does on your web app. It could be as simple as clicking the sign up button. Or filling the sign up form and clicking submit. This could be 2 different events.

But you would wonder why use 2 tools for tracking the same data? Well mix panel is purely an analytics tool. But intercom does more than that. It also provides the in-app messenger,  a chatbot if you will. Also one can trigger behaviour based on events. For ex: a ‘sign up’ event is triggered and we need to send account activation link upon every successful sign up. Now instead of configuring mailers in our rails app, we can just define behaviour in intercom to do some action whenever sign up occurs. And this behaviour could be sending emails or sending messages to the chat box. So I would say that primary purpose of intercom is to add messenger and add behaviour on events rather than doing analytics on those event data. Mix panel would be a better tool for this.

Why we need these tools?

But you would wonder how does this data help? Well, it gives you insight about how does the user uses your app. Considering the same example, by tracking those 2 different events, you would have knowledge that ‘n’ users visited the sign up page, but only ‘n/3’ signed up.

So now you can add events to more granular level i.e by adding events to every field. This will give you insight about which is that field which users hesitates to enter the information about. And so on and so forth and thus can look to change things with user behaviour in mind rather than guessing about it.

How to use these tools?

I wanted to integrate these tools with an rails application. Now the general way to use any 3rd party tool is to generate the api key/token , secret key by registering on the dashboard if these tools. And there are usually ruby gems / javascript existing for these tools to integrate with our application.

And it is exactly what you need to do. Lets look at both of these tools one at a time.

Intercom basically provides you 3 products. Intercom acquire, Intercom Engage and Intercom Resolve. The first 2 are of interest to me. Intercom acquire allows you to add messenger. Intercom engage allows you to add behaviour based on occurrence of events.

Now if you just want to add the chat box to your app, you can just use this gem intercom-rails.  The usage is pretty straightforward. Generate an app id through intercom dashboard. Use the gem to generate the config file for intercom. And use the generated app_id in the intercom config file. As I needed the messenger on just the production site, so I enabled it only for it

config.enabled_environments = ["production"]

and I wanted to record some custom data of the tracker users. Ex:

config.user.custom_data = {
  id: :id,
  user_name: :email,
  companies: Proc.new do |company|
    company.sites.map do |site|
    {
      id: site.id,
      name: site.name
    }
    end
end
}

Now what intercom does is whenever a user logs into your application, it sends this custom data about logged in user to the intercom just by using the custom_data defined in the initialisers file. If does not matter if the user logs in for the first time or 100th time.

Now stop here if you only wish to add the messenger, but if you are looking to track events and add behaviour based on those events, read on.

To add events, there is another ruby gem which you need to use and it is called intercom-ruby. This gem also lets you register users, add tags, send messenger apps. But then intercom-rails lets you register users to intercom. So we don’t really need to use intercom-ruby to send users data.

The documentation is pretty neat. So I will not repeat what is already mentioned there. You can read it here. But server side is not the only way to track data. There is also the javascript way of doing it. You can read about it here. I decided to do this with ruby as of now as it looked more neat.

Now follow these pictures to see how to setup behaviour based on events or filters:

Step 1: Open the Intercom engage dashboard

1

Now you can set up message name as an identifier for behaviour.

Step 2: Choose your audience

2

So there are various criteria available to choose from. You can setup any rule you want to filter your audience with. Also if you scroll down the list of user data, at the bottom of that list, you will find filtering based on events names.

3

As you can see there is an event name ‘Signed Up’. So whenever user signs up, this behaviour will happen, it could be send the user an welcome link in an email or send him an welcome message on his intercom messenger.

4

 

and you can create your message.

Now lets move onto mix panel.

The ruby gem which could be used for mix panel is mixpanel-ruby. Again you read the documentation about how to use the gem or read on the official website here.

Now if you have been following so far, you would have realised thats its a lot of code that you would need to write(ruby or javascript) to track events in multiple platform. So to avoid this hassle, there is another tool called Segment.

Segment allows you to send your customer data to just one platform i.e theirs and they take of the rest. They send the same data to intercom and mix panel and various other platforms they can be integrated with.

Now to use segment, there is a ruby library as well as javascript library as there are always. Looking at the documentation I realised the javascript library usage is also pretty neat and could be used easily. So we would be using that.

So to use it like any other js library, you need to include the segment script in web page head. And then there are couple of things you could do. You can either identify user which means let segment know which user is doing the event and send the event. Or you can directly send the event by calling track without any call to identify function.

Also for events which occur internally and does not really have a web page to show it for so that javascript can run, I ended up using the ruby library.

So, all you have to do is integrate just segment and it takes care of sending this data to all other platform of interest to you.

I hope it helps some of you.

Happy tracking.. !!!!

Using Null Object Pattern in Rails to improve code quality

If you have not read my previous post I wrote about Service classes, I would suggest to read that first as it is in continuation to the previous post. This is the link to previous post.

In this post we are going to look at another pattern that helps us in refactoring code, especially helps us in removing conditions. It is called Null Object Pattern.

This code is used to download the data dump based on some rules as always. But here is my 2 cents, do not even try to understand the code.

   def download_measurements
    specification = @inspection.specification
    serial_numbers = @inspection.get_serial_numbers
    inspection_results = @inspection.inspection_results.includes(:inspection_serial_number)
    row_list = []

    row_list << ['unit number', 'serial number', 'gage id', 
                 'inspected by', 'inspected on yyyy-mm-dd', 
                 'place', 'measurement', 'bonus tolerance', 
                 'actual measurement', 'text', 'remark', 
                 'non-conformance number']

    serial_numbers.each_with_index do |serial_number, index|
      specification.feature_repeats.times do |place_index|
        place_number = place_index + 1
        ir = inspection_results.collect{|i| 
             i if i.serial_number.number == serial_number}.
             uniq.compact.first

        specification.readings_required.times do |measurement_index|
          measurement_number = measurement_index + 1
          rm = ir.nil? ? nil : 
            ir.result_measurements.where(:place_number => place_number, 
            :measurement_number => measurement_number).first
          
          inspected_on_date = ir.nil? ? nil : ir.inspected_on.nil? ?
          nil : ir.inspected_on.strftime('%Y-%m-%d') 
          
          measurement_value = rm.try(:actual_measurement).nil? ? 
          nil : rm.try(:actual_measurement)
         
          measurement_value = rm.try(:measurement_result) == 'P' ? 'PASS' : rm.try(:measurement_result) == 'F' ? 'FAIL' : nil if specification.result_type == 'Attr'
          row_list << [index+1, serial_number, ir.try(:gage_serial_number), 
                       ir.try(:inspected_by), inspected_on_date, place_number, 
                       measurement_number, nil, measurement_value, rm.try(:information),
                       ir.try(:remarks), ir.try(:non_conformance_number)]
        end
      end
    end
    file_name = "Template" + "-" + @inspection.balloon + "_#{Time.now.to_i}.xlsx"
    file_path = "#{Rails.root}/tmp/#{file_name}"
    XlsxHelper.generate(row_list, file_path)
     send_file(File.open(file_path), :type => 'application/vnd.ms-excel', :filename => file_name)
   end

We clearly need to refactor because this code is difficult to understand even for the person who has written the code, forget the team who is working on the same project. And since this code is difficult to understand, it is difficult to debug and it is difficult to change as changes will come as they always do.

As I can see that this whole code first of all should not be a part of a controller method. Since the purpose of this code is to generate a sort of data dump in a csv file, I would make it a service class and call the methods of that class as explained in the previous post.

By just glancing at the code, I can understand that there is a header added somewhere in there and then there is some logic to add the data. So I will start by making a service class. And make these empty methods.

class ExportIdeData
  def initialize(inspection)
    @inspection = inspection
  end

  def run!
  end

  private

  def header
  end

  def add_data
  end
end

And my aim is to make controller code look like this:


  def download_measurements
    ide_data_runner = ExportIdeData.new(@inspection)
    ide_data_runner.run!
    generate_file(ide_data_runner)
  end

Now that we have defined a service class and has added methods to it, lets focus on this line of the old code:

  inspected_on_date = ir.nil? ? nil : ir.inspected_on.nil? 
    ? nil : ir.inspected_on.strftime('%Y-%m-%d') 

In this code, we see a complex logic of conditions which decide what value to return. If ir object does not exist, we want the value nil, if ir object exists but no value for attribute inspected_on exists in db, then we want nil. And if the value exists in db, we want to change the format of the date and then return that value.

If I have to apply such conditions to lets say only 1 attribute of the model, I wont mind adding all the conditions for once. But in our use case, when we have to apply such logic to multiple attributes of a model, it won’t just make sense to compromise on the code quality. And thus, Null Object Pattern helps us in cleaning our code.

So these are some of the changes that we make to our new service class.

  def header
    @rows = [['unit number', 'serial number', 'gage id',
              'inspected by', 'inspected on yyyy-mm-dd',
              'place',  'measurement', 'bonus tolerance',
              'actual measurement', 'text', 'remark', 
              'non-conformance number']]
  end

  def add_data(sheet)
    @serial_numbers.each_with_index do |sn, index|
      @place_measurements.each do |pc|
        ir = find_inspection_result(sn)
        rm = find_result_measurement(ir, pc[0], pc[1])
        data = [index+1, sn.number, 
                ir.serial_number, ir.inspected_by, 
                ir.inspected_on_rep, pc[0], pc[1], nil, 
                rm.measurement_value, ir.remarks, 
                ir.non_conformance_number]

        add_row_with(sheet, data, @header_values, 
                     height=27.571428571428573)
      end
    end
  end

Now do not get too much into the code. Just have a quick look at it, this code looks clean.The whole code is not important for you to understand for what we are trying to achieve here, pay attention to these lines:

  ir = find_inspection_result(sn)
  rm = find_result_measurement(ir, pc[0], pc[1])

These are some of the methods that that we need to define:

  def find_inspection_result(serial_number)
    ir = @inspection.results.where(:serial_number_id => serial_number.id).first
         || NilInspectionResult.new
    ir
  end

In the above code, I find the inspection result object and if it fails to find such object in database, then we initialize a new object of the class NilInspectionResult.
Keep in mind these are classes that do have a corresponding database table. It is just a plain ruby class which happen to be created under models folder.

This is how it looks:

class NilInspectionResult
    
  def gage_serial_number
    nil
  end
    
  def inspected_by
    nil
  end 
    
  def inspected_on_rep
    nil
  end
  
  def remarks
    nil
  end
              
  def non_conformance_number
    nil
  end 
end 

So, when we do not find an result object in database, a new object of our newly defined class NilInspectionResult has access to these methods defined above which a valid result object would have.
What I mean here is that remarks, non_conformance_number etc are attributes or methods defined in InspectionResult model and so we define the same methods in our new class also with values we expect them to return.

This also helps us in keeping our code clean but also easy to change. For ex: In future if client wants that instead of returning nil as the date for the case when result object does not exist, return the current date. So I just have to change the method in NilInspectionResult class to return current date and not nil.

Similarly look at this code:

measurement_value = rm.try(:actual_measurement).nil? 
  ? nil : rm.try(:actual_measurement)

‘try’ is just a fancy way to write if else conditions. And it is suggested to avoid such conditions whenever possible. So I would change the code to something like this:

def find_result_measurement(ir, pn, pm)
  rm = ir.result_measurements.where(:place_number => pn, :measurement_number => mn).first 
       rescue NilResultMeasurement.new
  rm
end

Here we find the result measurement object which also depends on the ir object. And in our previous method we have found the result object ir, and it could contain the actual inspection result object or a nil template of it(NilInspectionResult.new).

So in code to find the result measurement object, I use rescue to initialize a NilResultMeasurement object. And I add a class like this:

class NilResultMeasurement
  def measurement_value
    nil 
  end

  def pass_fail_result
    'N/A'
  end 
end

Now I think I do not need to explain why this above code is what it is. But one of the most important thing to remember when using Null Object Pattern is not to overuse it.

So I hope this helps you in avoiding conditional blocks whenever and wherever feasible to use this pattern. And I will say this again, we have not reduced the number of lines of code, we have infact increased the number of lines of code. But we have made our code looks much cleaner, easier to change and understand.

Using Service Classes to improve code-quality

ServiceClasses are nothing but plain old ruby classes. But they go a long way to keep your controllers thin and models thin. To show what I mean by this, lets look at some code. This is the code in controller to download data following some set of rules.

class ImportExportsController < ApplicationController

  def multi_column_download_template
    rows = []
    header = ['Spec Number', 'place', 'measurement',
              'measurement number']

    file_name = "multi-column-template" + "_#{Time.now.to_i}.xlsx"
    file_path = "#{Rails.root}/tmp/#{file_name}"

    specs = @inspection_master.row_no_wise_specs
    specs.each do |spec|
      header << spec.id.to_s + "#" + spec.characteristic
    end
    rows << header

    feature_repeat = specs.collect(&:feature_repeats).max
    measurement    = specs.collect(&:minimum_readings_required).max

    inspection = Inspections::Inspection.new(
                   :feature_repeats => feature_repeat, 
                   :minimum_readings_required => measurement)
    place_cols = inspection.calculate_records

    @inspection_master.inspection_serial_numbers.each_with_index do |d, index|
      rows << [index+1, d.place, d.measurement, d.serial_number]      
    end
  
    generate_and_download_file(rows, file_path, file_name)
  end

  def generate_and_download_file(rows, file_path, file_name)
    #code which generate a xls file and send it as response
  end

end

This is bad. The controller should not look like this. It is not thin. It is difficult to understand. And the bigger problem which is difficult to see the moment we write code is that things will change. Believe me change is the only constant. And the cost of those changes will be much more higher. So comes in Service classes.

The ideology behind service classes is that it should have only one purpose to serve and nothing else.

And I can clearly see a purpose which our new service class should serve and that is to provide the data for our template download and nothing else. I keep the service classes under app/services folder. Also I do not think I need to iterate much on the importance of the name of the service class you choose. It goes without saying that the name should tell the purpose it is going to serve. I will name my service class MultiColumnDownload and I put it under app/services folder. This is how the service class looks like:


class MultiColumnDownload

  def initialize(inspection_master_id)
    @inspection_master = InspectionMaster.find inspection_master_id
    @file_name = "Multi-column-template-" + "_#{Time.now.to_i}.xlsx"
  end

  def file_name
    @file_name
  end

  def file_path
    "#{Rails.root}/tmp/#{@file_name}"
  end

  def run!
    initialize_header
    find_specs
    insert_data
    @rows
  end

  private

  def initialize_header
    header = ['Spec Number', 'place', 'measurement', 'measurement number']
    specs = @inspection_master.row_no_wise_specs
    specs.each do |spec|
      header << spec.id.to_s + "#" + spec.characteristic
    end
    @rows = [header]
  end

  def find_specs
    @specs = @inspection_master.specifications
  end

  def find_feature_repeats
    @specs.collect(&:feature_repeats).max
  end

  def find_minimum_readings_required
    @specs.collect(&:minimum_readings_required).max
  end

  def insert_data
    @inspection_master.inspection_serial_numbers.each_with_index do |d, index|
      @rows << [index+1, d.place, 
                d.measurement, d.serial_number]
    end
  end

end

And now our controller looks like this:


class ImportExportsController < ApplicationController

  def multi_column_download_template
    download_object = MultiColumnDownload.new(@inspection_master.id)
    rows = download_object.run!
    generate_and_download_file(rows, download_object.file_path, download_object.file_name)
  end

  def generate_and_download_file(rows, file_path, file_name)
    #code which generate a xls file and send it as response
  end
end

In the controller, I just have to instantiate an object for our newly created service class and we call this object service object. And call the run! method. Keeping our controller code very thin just the way it should be.

Now this is the code I like and proud of. Not the earlier one. Now in future if I want to change the formatting of this template or add or remove some data, I know where to look for the code and where to make changes. Also I do not have to change anything in my controller code as long as the service class returns data.

Have we reduced the number of lines of code? NO. In fact we have increased the lines of code by at least one and half times.

Have we reduced the complexity of code? YES. Now the code is easier to understand and maintain over long term.

I can only hope that you find this useful and make service objects without any fear of increasing code complexity or number of lines of code. I certainly do..!!!

(p.s. I have reduced the complexity of the controller to not deviate away from what we are trying to understand here.)

Nested module definitions

When we define nested modules like this:

module A
  X = 1
  module B
    X = 2
    module C
      def self.print_const
        puts X
      end
    end
  end
end
  A::B::C.print_const  => 2

and when we do like this:

module A
  X = 1
  module B
    X = 2
  end
end

module A
  module B::C
    def self.print_const
      puts X
    end
  end
end
  A::B::C.print_const  => 1

Even though both method calls to print_const looks same, and should return same result. But it returns different values of the constant.

Reason:
When you do this in first case:

module A
  X = 1
  module B
    X = 2
    module C
      puts Module.nesting
    end
  end
end

and this gives:

[A::B::C, A::B, A]

So ruby looks for the constant X in the order as A::B::C, A::B, A. and it loads wherever it finds first, and as in our scenario, under module B.

And in second scenario:

module A
  X = 1
  module B
    X = 2
  end
end

module A
  module B::C
    puts Module.nesting
  end
end

and this gives:

[A::B::C, A]

Here since the nesting of the module is different, it only search in A::B::C and A, skipping A::B. So it finds constant X under module A.

Blocks, Procs & Lambdas revisited

Blocks, Procs & Lambdas are one of the most fun things in ruby but also very difficult to understand. This is my attempt to make these things a little simple for you.

What are blocks?

A piece of ruby code within a do..end or within curly braces {} is a block. For ex:

[1,2,3,'a'].select do |d|
  d.is_a?Integer
end

or

[1,2,3,'a'].select {|d| d.is_a?Integer}

We should also notice here that blocks breaks one of the most basic and yet powerful fundamentals of ruby that everything in ruby is an object. Well blocks are not objects. They are just piece of ruby code.

Now imagine when we have more than 1 array to select only the integer values. Ex:

[1, 2, 3, 'a'].select {|d| d.is_a?Integer}
['b', 'c', 5].select {|d| d.is_a?Integer}
['a', nil, 4 ].select {|d| d.is_a?Integer}

This is not very ruby like. We clearly breaks the DRY(Do not repeat yourself) rule. We are repeatedly writing the same block of code again and again. Now only if we could somehow save the block of code in a variable. Enter Proc.

What is a Proc?
In most simple way, Procs are named blocks. For ex:

p = Proc.new {|d| d.is_a?Integer}
puts p.class => Proc

So p is an object of class Proc unlike blocks.
Now we know how to save a block of code in a variable, lets use that knowledge to make our code dry.

[1, 2, 3, 'a'].select(&p)
['b', 'c', 5].select(&p)
['a', nil, 4 ].select(&p)

Then, what about lambda.

What is a lambda?
Lambda is just like a proc with very subtle differences between them. But before we get there, lets see how do we declare a lambda and how to use it. Ex:

p = lambda {|d| d.is_a?Integer}
puts p.class => Proc
[1, 2, 3, 'a'].select(&p)
['b', 'c', 5].select(&p)
['a', nil, 4 ].select(&p)

Yes, lambda and proc both belong to class Proc.

Then, is there any difference between them?

Difference between proc and lambda:

1. Proc do not care about the number of arguments passed. It assigns nil to any missing argument.
Ex:

p = Proc.new {|d| p d.class}
p.call => NilClass
p.call(3) => Fixnum

But had it been a lambda,

p = lambda {|d| p d.class}
p.call would raise
ArgumentError: wrong number of arguments (0 for 1)

, as it cares about its arguments unlike Procs.

2. when lambda is called, it returns control back to the calling method. Whereas Proc does not go back to the calling method. Ex:

def test_proc
  p = Proc.new {return 'In proc'}
  p.call
  'In test_proc method'
end
test_proc=> 'In proc'
def test_lambda
  p = lambda {return 'In lambda'}
  p.call
  'In test_lambda method'
end
test_lambda=> 'In test_lambda method'

I hope this would make understanding these concepts a little bit easier.

Contributing to Open-Source Projects

Today I would like to share what I have learned from the very little open-source contributions I have made so far. But before I do that, I would like to write a little bit about myself. I am ruby on rails developer at JoshSoftware for the past 3 years. Before that I was studying Electronics in Pune Institute of Computer Technology, Pune. Yes.. you read that right. I was an electronics student in computers college. The reason I am laying out the details is, I do not want you to think that I am some big shot who has been working for a decade. I am just a guy who likes to write programs and do web development.

So, here is the list of hurdles I came across until I made my first open-source contribution:

1. Which projects should I contribute to?
Thats a valid question. There are tons of projects out there. How do I find out about these projects? In my case I have been very fortunate to work on open-source technologies, and at a company that promotes doing contributions. My daily work tool involves ruby which is an open-sourced language and rails an open-source framework. Starting with ruby, when I say I code in ruby, it also heavily involves using gems (aka libraries). As of today, there are 91,349 gems hosted on rubgems.org. That means I have at least 91,349 open-source projects to contribute on. And rails, I think contributing to rails is so easy, not because the code is simple to understand, it is not. But because of the community. Everyone helps you out if you are stuck at something. Here is an example:
I had sent a pull request with different commits. I had added example for squish method, remove method and a test case for that.
os1
In my diff, you can see there is an extra line added which is not needed. And Zachary Scott , a member of rails core team, asks me to remove that extra line.

Now, I also saw that extra line while submitting the pull request, but I just ignored it. Because I did not knew why that line came even after I have not added it. So I send him a screenshot of the code at my end that I have no extra line break.
os2

And then Eileen M. Uchitelle came to my rescue, who I have never met in person and she has nothing to do with the pull request that I have sent, but she still helped me out. See it here:
os3
So it was not a new line, but an extra space or a tab.

Now, another rails committer Vijay Dev gets involved with the PR, and asks me to squash all commits into 1 big commit. I did that and I sent a new PR with squashed commits. And then Abdelkader Boudih, who is also part of the rails core team, asks me to force push it. It is exactly the reason I sent a new PR because I wanted to avoid force push.
os4
And then he asks me to remove the “[ci skip]” tag from the commit. Because I have added a new test case. In case you do not know, if you have made changes like changing documentation, then there is no need to run the test cases for such PR. But I have a new test case, so I had to remove the ci skip tag.
os5

So, you can clearly see the mistakes I have made, and how everyone helped out. Here is the PR.

2. Am I good enough?
It is something that I still ask to myself. Am I good enough to contribute to somebody else’s project, may be I should work for 5 more years and then I will make contributions. But believe me, you are good enough to contribute to any project you like from the day you start writing that “hello world” program in your favourite language. The only regret that I have is why did I start so late … why it took me at least 2 years to make that first contribution. Because contributing to open-source projects is not just about sending a PR for a new feature that you wish to see or fixing a critical bug which nobody seems to solve. There is so much more to it. You can help out in documentation, you can add comments to methods explaining what they do or you can fix failing test case or add a new one which you think the author has missed.

One of the best ways to start contributing is by observing what kind of pull requests other developers send, and you will start finding a pattern in those which will help you send your first PR.

3. What will I gain from it?
Satisfaction, Recognition, Learning. These were the main reasons I started contributing in the first place.

I think these are the main hurdles I faced.I hope this blog post helps some of you and you can avoid the mistakes I have made. And it would be great, if you could share your experience of contributing to open-source projects. Mention it in comments or tweet me at jainrishi15 if you have a similar post and I will try to include it in the blog post.

UPDATE:
I came across this post by PJ Hagerty which is about how and why to contribute to ruby.

Migrating from ruby 1.9.3 to ruby 2.0.0

Since support for ruby 1.9.3 is suppose to end in 2015, it was high time I migrate from ruby 1.9.3 to ruby 2.0.0, and eventually to ruby 2.2.0. These are the steps I followed while migrating to ruby 2.0.0 and the problems I faced.

1. bundle install for ruby 2.0.0

2. run test cases.
Few test cases failed. The error message was:

NoMethodError:
  private method `initialize_dup' called at line:.. in file ....

When I looked at the line which was producing this error, it was

user.dup

It turns out this problem was fixed in Rails 3.2.13. So I upgraded the Rails version to 3.2.13. If you want to read more about, here is the github issue page.

3. Bumped up Rails to 3.2.13 in Gemfile.
4. bundle install again.

Rails locked at 3.1.11

So, did

bundle update rails

And, another error: devise_invitable(0.6.0) depends on Rails >= 3.0.0 and = 3.0.0 and < 4.0 .

So came step 5.
5. Bumped devise_invitable to 1.0.0 in Gemfile.

6.

bundle update devise_invitable.

7. Another error: devise_invitable depends on devise ~ 2.0

I was on a much lower version of devise. So I upgraded devise to 2.0.0 in Gemfile.

8.

bundle update devise

Another error popped up, devise 2.0.0 depends on railties ~3.1 and I had rails pointed to 3.2.13. Now growing with frustation, I did:

bundle update

and upgraded the whole stack and no error.. boom ..!!

9. Run test cases again and the previous test cases which were failing, passed, but new ones failed now. The error was:

Paperclip::Errors::MissingRequiredValidatorError

When I did `bundle update`, it updated paperclip to 4.2.0 and in this version, in your model you need to mention the content_type and file_name validation of the file or explicitly mention that you do not need these validations. This is how you can do it all:

validates_attachment_content_type :image, :content_type =&gt; [&quot;image/jpg&quot;, &quot;image/jpeg&quot;, &quot;image/png&quot;, &quot;image/gif&quot;]
validates_attachment_file_name :avatar, :matches =&gt; [/png\Z/, /jpe?g\Z/, /gif\Z/]

or

do_not_validate_attachment_file_type :image

You can read about it more on this stackoverflow thread.

10. So I changed my models accordingly.
11. ran test cases again and boom.. all test cases passing..!!

And finally rails server starts. But this does not mean I will not face any problems henceforth because I have 78% test coverage and this means there is considerable chunk of code which is not checked yet, this means a day of manual testing awaits me..!!

I will keep updating this post with new steps and problems I am facing. But until then,

12. Manual labour .. !!!