I was working on client side searching in an ember application. The requirements was very simple, consider the following array of strings,

"We aim to be simple to integrate with any modern Rails application",
"We need an application that can display the current state of the orders",
"The intent behind it was to keep setup as easy as possible"

and I search for the query "application", I should get the following as output.

"We aim to be simple to integrate with any modern Rails application",
"We need an application that can display the current state of the orders"

But, if I search for "current orders", I should get the following as output,

"We need an application that can display the current state of the orders"

So clearly, it was keyword based searching.

I ended up finding just the right library, lunr.js. I wanted it to work with my ember model’s very robustly. So I ended up creating a ember-addon for it and named it (according to the pseudo addon naming convention) as ember-cli-lunr.

Hope you all find this addon useful in your ambitious search applications. And please help me make this ember addon better by submitting PR, feature request, issues or just a thank you (your appreciation moves me forward).

Recently, In Paperclip (4.1.1) I had to change the hash_secret, which is used for the purpose of URI Obfuscation. But, the problem was that there had been many files in production generated with the old hash_secret. Simply just changing the hash_secret would invalidate all the old URL’s as paperclip does not store the URL’s of the files instead it generates using the path option given to it (which would obviously contain the :hash interpolation).

It was evident that I had to write a migration to move the already existing files from old location to new location (We were storing the files in S3). Also, I wanted the moving part to simply look like

old_object = bucket.objects[attachment.file.old_path]
new_object = bucket.objects[attachment.file.path]

old_object.move_to(new_object)

In order for file.old_path to work I had to override Paperclip::Attachment and add old_path method to it. Although, it turned out that I had to override three more functions, it was worth it. Besides, this override was just a temporary one.

# config/initializers/paperclip_override.rb

require 'openssl'

module Paperclip
  class Attachment

    # Old path overrides
    def old_path(style_name = default_style)
      path = original_filename.nil? ? nil : interpolate(old_path_option, style_name)
      path.respond_to?(:unescape) ? path.unescape : path
    end

    def old_path_option
      # Replace this with your :path option replacing :hash with :old_hash
      "file_attachments/:id/:old_hash.:extension"
    end

    def old_hash_key(style_name = default_style)
      data = interpolate(@options[:hash_data], style_name)
      OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@options[:hash_digest]).new,
        "<YOUR OLD HASH_SECRET>", data)
    end
  end

  module Interpolations
    def old_hash attachment=nil, style_name=nil
      if attachment && style_name
        attachment.old_hash_key(style_name)
      else
        super()
      end
    end
  end
end

Here is the rake task which moves the file from old location to the new location just as I wanted it to be,

# lib/tasks/paperclip_hash_secret_migration.rake

namespace :paperclip do
  task :s3_migration => :environment do
    Attachment.all.each do |attachment|
      s3 = AWS::S3.new(AWS_S3["credentials"])
      bucket = s3.buckets[AWS_S3["bucket_name"]]

      old_object = bucket.objects[attachment.file.old_path]
      new_object = bucket.objects[attachment.file.path]

      puts "Moving object from #{attachment.file.old_path} to #{attachment.file.path}"
      old_object.move_to(new_object, { :acl => :public_read })

      # Perform any additional operations you want with
      # old_object and new_object here.
    end
  end
end

If you are using a File Storage, then you could find appropriate ruby code to move file from one path to another on Google.

It all started with a project in which I was working on, it contained too many constant tables like Country, City etc. It was a team of 3 people including me. We had tough time querying to check if the user belonged to a certain country.

if user.country.name == "India"
  # Some logic
else
  # Some logic
end

The above code was present all over the place. Being obsessed with elegance, we all wanted something like the following,

if user.country.india?
  # Some logic
else
  # Some logic
end

Additionally, there were many places in which we had to query for the country record.

  Country.find_by_name("United States of America")

And again we felt something wrong and wanted it to be more elegant and easy to read, so we decided we wanted to replace it with this,

  Country.united_states_of_america

We wrote a module to be included in all the constant model’s and being open source enthusiasts we extracted it into a gem which is hosted in github.

This module is young, so we need support from people to make it better. So feel free to contribute to the repo.

Clearly everybody using rails will have this problem. When your model gets bigger and bigger, you will find it difficult to spot your attributes in the rails console. So let’s clear this messed up console and format it a little bit. We have a gem called ‘awesome_print’. Install it using

gem install awesome_print

Then open your ~/.irbrc file and add these lines to it.

# load libraries
require 'rubygems'
$LOAD_PATH<< '/path/to/awesome_print-x.x.x/lib'
require 'awesome_print'

usually if you use RVM and ruby 1.9.3 your path to awesome_print gem will be like

/home/username/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-x.x.x/lib

now fire up your rails console and try to print any object prepended with ‘ap’

ap User.first

Hooray!!! We formatted the console. But wait, we missed something. Printing everything with ‘ap’ prepended seems inappropriate. So let’s make awesome_print our default formatter. Now, open your ~/.irbrc again and add this line after requiring awesome_print.

AwesomePrint.irb!

Now you will be able to format everything you print beautifully. And you can add options to awesome print. See the documentation for more details.

Enjoy hacking !!!

Let's debug easily - git bisect

Imagine the scenario where your code has been reported for a bug and you don’t know exactly which part for your commit history induced this particular bug. But you sure know a past commit where this bug never existed (let’s call it “good commit”) and there are around 100 commits in between the “good commit” and your current commit(which we can call as “bad commit”).

So you are in a situation where you want to review all the 100 commits in between the “good commit” and the “bad commit”. Not a plausible solution, is it?

So what’s the way to avoid “searching" all 100 commits to find the buggy code. You got it right. Yes, do a binary search. Since we are lazy, we don’t want to binary search 100 commits which will take us log2(100) = 7 (approx.) steps to find the buggy branch. Luckily we have a life saver tool called bisect tool from git. Let us see how it works.

In your current branch, you have to do

git bisect start


This command simple starts the bisect tool.Then you have to mark the bad commit as bad. We can do that using

git bisect bad

Then we have to tell the bisect tool about the good branch. You can give the commit hash of the good commit. You can obtain the commit hash using 

git log

and then

git bisect good [good commit hash]

Now you will be surprised to see that the bisect tool takes you to the center commit of the good and the bad commit. At this point, you can run your test and see if the bug that was reported exists. If it doesn’t, then you can mark the commit as good using

git bisect good

else you can mark it as bad using

git bisect bad

So this takes you to the left or the right of the current commit you are on. This looks so simple, ain’t it?

Finally at the end don’t forget to stop the bisect tool using

git bisect reset

this will reset your HEAD pointer to where you were before you started, else you will end up in a wierd state.

Reference:

Thoughtbot Blog post on git bisect

git-scm reference

Happy hacking….!!!