Ruby on Rails

Depends how you interpret things

Spree Extend: Updating eligibility criteria for any existing promotion rule

As I mentioned in my last post spree-extend, how to create custom promotion rule(s) while working with Spree based e-Commerece website. Last weekend, I faced a situation where I need to update the existing promotion rule to handle some specific condition.

For example, when I select “Product(s)” spree default rule, it gives us the option to choose products manually or choose by product group and its working as expected. Later, my client told me he wants, when he selects by product_group he can actually select some Taxons/Tags so that only the products belongs to that product_group and has taxon(s) listed there are eligible for this promotion.

For updating any existing promotion rules in spree there are few generic steps we need to follow,
Step1. Extend the corresponding spree->promotion->rules model class. Here, I created a file app/models/promotion/rules/product_decorator.rb.

Promotion::Rules::Product.class_eval do

Step2. Create the attribute accessors/ accessibles for new attributes you needed.

Promotion::Rules::Product.class_eval do
  has_and_belongs_to_many :taxons, :class_name =>"::taxon", :join_table => "taxons_promotion_rules", :foreign_key=>"promotion_rule_id"
  attr_accessible :taxon_ids_string
  //setter and getter methods
  def taxon_ids_string
  def taxon_ids_string=(string)
    self.taxon_ids = string.split(",").map(&:strip)

Step3. update the corresponding View file for the same rule in admin/promotions/rules/_product.html.haml or .erb if you are using erb. Add the required code for handling the same. In My case I added one TokenInput object to get multiple taxons selection. Add code something like this… where-ever you think is more suitable for you.

%p{:class=>"field products_rule_taxons"}
    = "Choose Taxons"
    = taxon_picker_field "#{param_prefix}[tag_ids_string]", promotion_rule.taxon_ids_string

There are 2 different ways of adding this to view file. One, you can write a decorator and tell before/after which object you want to put this code. Second, you can re-write the complete file and do whatever you need. Upto you.

Also, taxon_picker_field is a helper method which I created for creating the tokenInput/tokenizer object. Create the AdminBaseHelper decorator file, if not exists and put the following code or something like that,

Admin::BaseHelper.module_eval do
  def taxon_picker_field(name, value)
    taxons = value == "" ?  [] : Taxon.where("id in ('#{value}')")
    taxon_names_hash = taxons.inject({}){|memo,item| memo[] =; memo}

Step4. Update the eligible? and/or eligible_products methods as per your rule updations. Here in my case I just need to change the eligible_products method. Add the following code in app/models/promotion/rules/product_decorator.rb

  def eligible_products
    if product_group
      return self.taxons.collect(&:products).flatten

Or something like that as per your requirements

And yes, We are good to go and the new rule criteria will be applied from now on-wards.

Good luck, In case of any query, feel free to ask here or email me at


Spree Extend: Creating Custom Promotion Rule

I’m working on an E-commerce website for sometime now. We are using spree as backbone of the project and customizing where and when its required. Spree is quite good and fully functioning E-commerce Rails engine which give you base to build a e-commerce website quickly and with lesser efforts.
One of the main features of any e-commerce website is Promotions/Coupons. Spree also has a built in spree promotion module which is ready to use with predefined rules and adjustment calculators. Being an ADMIN I can define any new promotion rules i.e. first order, user specific, products specific etc. Also I can define the actions like ALL or ANY. You can have a look on spree_promo module at spree_promo and see how it works.
Spree already provides some 4-5 predefined Promotions Rules on the basis of which every order get cross-checked whether some adjustments has to be done or not. Most of the time these rules/calculators are more than enough in general usage, but sometimes we need few very specific CUSTOM rules to be defined. Here I’m going to explain how easy it is to create new spree promotion rules.
Create Promotion Rule:
step1. create a model file app/models/spree/promotion/rules/my_custom_promotion.rb

  module Spree
    class Promotion::Rules::MyCustomPromotion < PromotionRule
      // required associations or preferences if any
      // required attribute accessible if you need to protect some attributes from 
mass assignment
      // match polices and operators
      MATCH_POLICIES = %w(any all) // as per your requirement

      def eligible?(order, options={})
        // This method is the place where every order is being verified whether its 
eligible for any promotional discount

Step2. Add this custom promotion rule to default spree promotion rules list. Write the following code in either application.rb or some initializer

  initializer "" do |app|
    app.config.spree.promotions.rules += [Spree::Promotion::Rules::MyCustomPromotion]

Step3. Add the translations for name & description for custom rule as spree use the standard view for all with Translation method t(‘name’) or t(‘description’). write the following code in your config/locales/en.yml(or any other locale file if you are having multilingual products).

        name: Products By MyCustomPromotion
        description: Add products from MyCustomPromotion

Step4. create the view partial file for the custom promotion rule. add a file to app/admin/promotions/rules/_my_custom_promotion.html.erb or haml or something else depending on the template engine you are using for views.

And, restart your application server and you are good to go. Now whenever you are going to edit the Promotion, in the promotions rules list you will see you custom rule also available.

NOTE:: if you want some custom price adjustments/calculations as well, then you have to create a new calculator. E.g. If I want to define some flat percentage benefit on my custom promotion we have to create app/models/spree/calculator/flat_percentage.rb

  module Spree
    class Calculator::FlatPercetange < Calculator
      // preferences if there are any.
      // attributes accessibles
      def compute(object)
        // main method where we have to compute the adjustments we have to made.

I hope it helped someone. In case of any query, please feel free to ask here or drop me a mail at

Titanium : Passing parameters between windows [How to make things global]

While working on any titanium application, one of the common possibilities is to use some variables/constants across the windows. In Titanium, windows use to have their on context. That means the variables/values available on one window are not available on the others linked windows by default. So, if we are required to pass parameters between windows,  there are many different ways to achieve this. So, choosing a perfect approach for passing variables/parameters within windows depends on the requirement we are having. In our last project we had used few different approaches as per our requirements. Few of them are :


There are few cases where we need to store values to be used everywhere in the application, and we want to retain those values even when application is not-running/ in-background. The App Properties module is used for storing application related property/value pairs which persist beyond application sessions.

We can set the property/value pair as:


Now, as property/value pair is set. Now I can simply retrieve that value where I want in the application as:

var value = Titanium.App.Properties.getString("my_prop");

While setting properties in Ti.App.Properties, we have to make sure few things:
>> we are actually making things globally available, means whatever values we are storing, should not conflict with already existing global titanium constants, otherwise functionality will suffer. For more information, check Titanium documentation at Titanium.App.Properties


There are cases, when we need few values to be available all over the application, but when we close the application, those values should not be available any-more. For example,  while working on an application I need to access the current locale for the device for different purposes. But when I closes the application, I don’t need that value to persist as use can change the locale in-between as well. So better to make request to get these kind of values when app initializes and persist those values throughout the application session.

We can declare methods and variables to be globally available with Ti.App as:

Ti.App.sample_variable = “xxxxxx”;

Ti.App.sample_function = function(_args){ //your code for the function };

Then we can use this variable/method anywhere in our application. It will be available in the application session.

App Level Global Declaration:

For past weeks I was wondering about what are the best ways of writing titanium javascript code to make it more generic, reusable and more modular. Tweetanium, the sample application build by titanium/appcelerator team to help people, posses a new approach for design/creation of titanium based applications. Approach is to maintain an Application Level NAMESPACE and write each and every single peace of code wither to that namespace or sub-namespaces to that. e.g.

In app.js of your application,


//suppose name of my application is sample, so defining the global namespace or placeholder for my application

var sample = {};

Now I can define my UI, models, controllers methods and variables in the corresponding namespace or placeholder to make them more structured. As,

sample.UI = {};

Now if I want to declare any method or variables, I can place them in corresponding files and assign all the methods/ variables to their parent placeholder.



sample.UI.xxxx = function(_args){

//write you code you want to use.



For knowing more about how to write MVC structure applications with titanium, stay tuned, as I will be back soon with one more blog post for the same

Passing parameters within successive windows:

If we just need to pass parameters/values between 2 successive windows, then it can be done via sending values as a part of window object it self. Like. for example I’m working on a map related stuff and when I click on a button which leads me to the next window which shows some data corresponds to my geolocation position. Then while creating the window element we can pass those values as part of window object itself. As:

## window1.js


var button = Ti.UI.createButton({

label: “button1”,

height: “20dp”,

width: “100dp”


button.addEventListener(“touchstart”, function(){

var window2 = Ti.UI.createWindow({url:”window2.js”});

window2.sample_value = “xxxxxx”;, {animated:true});



var window = Ti.UI.currentWindow;;

//this will return “xxxxxx” as a values;

These are the few ways of passing variables globally which I used till now. For any query Contact me anytime, or reply back.

Blogging- an art ……!!!

While often regarded as a platform for people to share their personal stories, a blog can also be used to tell the story of an organization. Whether showcasing your work, offering behind-the-scenes glimpse into your non profit, highlighting the people you serve, or advocating a particular point of view, a blog can be a powerful — and influential — communication and public-relations tool for your organization.

So how do you create a blog? Let’s say that you’ve already spent time reading other blogs and articles on how to successfully maintain and promote your blog. (More Resources at the end of this article will help you get started.) You’ve defined your goals, your target audience, and the type of content you’ll provide. Your next challenge is to pick the blogging tool that offers the right features for you.

There are a number of good blogging tools, but choosing among them can be confusing. In this report, we’ll take a detailed look at the top blogging tools out there and outline key considerations for selecting a blogging platform, including the skills required to set it up; the ease with which you can post to it; whether you can upload images, video, or audio to it; its ability to moderate comments and prevent spam; how closely you can tailor its design to match the look and feel of your organization’s Web site and other collateral; and tools you can use to track who’s reading it.

The seven blogging platforms we’ve chosen for comparison are

  • Blogger,

  • LiveJournal,

  • Typepad,

  • Movable Type,

  • WordPress,

  • ExpressionEngine, and

  • TextPattern.

We chose these tools because they are the ones most commonly used to create a typical non-profit blog — by a long shot. 77 percent of all the bloggers included in the Non-profit Blog Exchange and 81 percent of respondents in a survey of serious bloggers conducted by ProBlogger used one of these seven tools.

  • Features and Functions

Blogging tools are designed to be easy to use. They generally don’t provide all the advanced features of a complex content management system, but rather does one task publishing a blog very well. To this end, they can help us:

  • Create posts. Since the purpose of a blog is to be able to post new text or information to the site frequently, creating posts should be quick and easy.

  • Upload pictures and multimedia. Many blogs go beyond text to include photos, video, or audio.

  • Display posts to visitors. A blogging platform can make it easy for readers to view your posts and to comment on them.

  • Moderate. While it’s typical to allow visitors to post comments to a blog, different platforms provide varying levels of help to weed out inappropriate contributions.

  • Publish RSS feeds. RSS feeds allow more Internet-savvy users to subscribe to your blog.

  • Configure the appearance and layout. Tools vary widely in the degree to which they allow you to configure your blog, and the methods they offer to do this.

  • Find support. Not every blogging tool offers the same degree of support: while some offer personalized assistance, others have forums where you can find answers to your questions.

  • Host your blog. While some blogging software lives on your own server, others are hosted by the vendor.

  • Get stats on your blog. Reporting features will help you see how many people are visiting your blog, and which posts are most popular.

  • Comment spam: Sad to say, spam is a problem on blogs just as it is in email. Comment spam, as you would expect, is left in the comments of a blog. It usually includes a few words and a link to a Web site. The point for the spammer is to get as many links as possible to the Web site, giving it higher search engine rankings.

  • Trackbacks: Trackback technology helps bloggers link back to other posts on related subjects. Functionally it’s a little complicated: If you’re posting about something you’ve seen on another blog, look for the Trackback URL. Paste that URL into the allotted spot in your own blogging software, and the two pieces of blog software will communicate, building a link from the original post to yours

  • Blogger

Blogger is a free, hosted blogging tool. It’s one of the oldest blogging tools around and today has millions of users. Blogger promises that you will be blogging within 10 minutes of coming to the site, and in fact does deliver on that. This tool is about the simplest one around, and though free, nonetheless has an impressive array of features.

The biggest hole in Blogger’s offerings is the lack of post categorization, followed closely by the need to know HTML and Cascading Style Sheets to make custom changes to the templates provided. Unlike some of the most complex hosted services, Blogger doesn’t make customization easy, though it does provide some attractive skins to choose from.

One unusual feature of Blogger is the integration with the Audioblogger service. Program the Audioblogger number into your phone, and you can put audio recordings on your blog quickly by simply calling the number and recording yourself. This offering is unique among blog software packages.

Of special note is that Blogger does allow you to FTP the files generated for your blog to your own Web site. Used together with customization of the Blogger template, this fairly unique functionality means that your readers may never realize that you are using Blogger. It also means that you can publicize your own domain name, rather than the more usual Blogger URL:

Blogger is perfect for the future blogger who’s in hurry and less than interested in design customization. If your priority is to start blogging now, you can’t do better than Blogger. Clearly, it’s also a great tool for those on a budget, since there are absolutely no costs. In fact, you need not even have a Web site or a domain name, so you can literally get started using Blogger without spending a penny.

Very few professional Bloggers stick with Blogger for very long, if they even start there. Because it is so simple, and perhaps because it is free, most professional bloggers choose to use blogging software that has more prestige (read: is harder to set up and install). However, it is an ideal tool to use when first beginning, especially if you want to test blog for a couple of weeks before devoting any serious time or money to a blog.

Cost: Nothing

Time to launch: 10 minutes

  • Typepad
    Typepad is one of Six Apart’s hosted half blogging software services (read about Movable Type below) and one that has proved very popular with journalistic blogging efforts. Jim Romenesko uses Typepad for his Obscure Store blog; Joel Achenbach of the Washington Post writes Achenblog using Typepad.

The Typepad pricing scheme and features are divided into three levels: Basic, Plus, and Pro. Design customization is extremely limited at the Basic level and only fully accessible at the Pro level. If you want to run a group blog, or give some people editor access and others publishing access, you must go with the Pro account.

At all account levels, Typepad has a built-in feature called Typelists that allows you to build lists, associating each item with a URL. These lists can be added with a minimum of fuss to the left- or right-hand column of your blog – no need to touch the templates. Use a Typelist for your current reading list, links to other blogs, or links to new stories.

In some ways, it is actually more usable than its elder brother Movable Type. Typepad is a good option for users who want to get started quickly but still want all the bells and whistles. Customization is possible, but complicated, so it’s also a good option for those who just want a blog that works without fussing too much over how it looks. However, Typepad Plus and Pro do a better job than most blog software at allowing you to configure layout options without having to go into the templates.

Cost: $4.95 – $14.95 monthly, depending on level of service chosen

Free trial: 30 days

Time to launch: 20 minutes

  • WordPress
    WordPress is a solid, powerful blogging system ideal for publishers who are on a budget but who don’t want to give up any functionality. Professional blogger Darren Rowse maintains nearly 30 blogs using WordPress, from his popular ProBlogger to an Athens Olympics Blog. In two weeks the Athens blog received close to 2 million readers, said Rowse – a real testament to WordPress’ ability to handle heavy traffic loads.

Each WordPress post is formatted with search engine friendly URLs that also look good to humans. Comments can be extensively moderated: you can review them before they go live. You can also filter comments containing certain words or more than a certain number of links.

WordPress’ built-in blogroll management tool allows you to categorize blogs, set criteria for the display order of the links, and turn off and on visibility. You can also import an existing blogroll from some link manager services.

This software has inspired numerous developers to write plugins and extra features for use with WordPress, which makes plugin installation a quick and painless affair. You will find that the selection of additional themes (or skins), for instance, numbers in the hundreds, and that WordPress fans and friends have developed tools for adding photo galleries, a music player, an event calendar, and even geo mapping.

WordPress promises a 5-minute installation, but for that to be true you do have to have some familiarity with uploading files to a Web server and using an FTP client.

Cost: Free

Time to launch: 20 minutes

  • Movable Type

Movable Type, created by Six Apart, is perhaps the best known of all blogging software tools. Built by a husband and wife team looking for a better tool for blogging, the system is powerful, but not simple to install or use. Although it has been used to create Web sites that don’t look entirely like blogs, doing so requires quite a bit of code tweaking. Movable Type is used by blogger Joshua Micah Marshall to create Talking Points Memo, and by Kevin Roderick who writes the L.A. Observed blog.

As a blogging tool alone, Movable Type has nearly every feature you might desire, and continues to add more. Many of their users are highly technical themselves, and have created additional plug-ins that can be added to the standard installation. You might say that Movable Type is the blogging package chosen by bloggers who care what other bloggers think, and who notice and appreciate other Movable Type blogs. If you are looking for street “cred” in the blogosphere, this is the software for you.

The least attractive functionality of Movable Type is the need to rebuild the blog whenever you make a change to a template, a configuration setting, or add a new category. Waiting for the rebuild is annoying, to say the least, and certainly slows down any customization work you do to the design or layout. This can be addressed by turning on dynamic page-building, but some users have found that the server load that occurs as a result is unacceptable to their Web host.

For the non-technically inclined, installation of this software can be quite a challenge. Don’t attempt it all if you aren’t already comfortable with uploading and downloading files to a Web server. There are several Web hosts that offer Movable Type installation as part of their package of services.

There is no trial period for Movable Type, but there is a free version of the software that you can download and install. The paid license entitles you to support, some promotion, and discounts on future upgrades.

Cost: MT’s pricing scheme is fairly complex. Personal users will pay at least $69.95. Commercial users pay at least $199.95.

Time to launch: 2 hours

  • Expression Engine

Machine’s Expression Engine isn’t well-known, but that shouldn’t stop you from giving this powerful and extensible software a try. It is technically more accurate to call Expression Engine a content management system, rather than just a blogging software tool. However, it grew out of blogging and has all of the blogging bells and whistles: moblogging, Trackbacks, archiving and so on. Dennis Lloyd uses it for the independent information resource iPodlounge.

In addition to the usual set of blogging functionality, Expression Engine has incorporated modules for image galleries and a mailing list. Uniquely, you can crop, resize, and rotate images in the Expression Engine photo gallery tool, in addition to batch processing a set of images. The people and search engine friendly URLs the system generates are of particular interest to bloggers looking for good search engine listings. You can run multiple Weblogs through the same installation of Expression Engine, and each “new post” page can be customized exactly to fit the use. Most blog software limits you to title, entry, extended entry, and excerpt fields. With EE, you can rename those to suit your publication and add more as needed.

Templates are editable online through a simple textbox interface, but you can set up the system to generate files you can download and edit with an HTML editor. Learning how information relates and how to link across the site is a challenge: expect to spend several hours learning how to use this system. Your reward will be incredible flexibility in building a site that has constant updating needs, blog or not.

Expression Engine is ideal for publishers that need to do more than just blogging; this system is ideal for handling hundreds of members, multiple user groups with different editing privileges, and sites with several blogs. Technically speaking, it’s not for the faint of heart.

Cost: $149 for a non-commercial license, $199 for a commercial license
Free trial: 14 days if installed on your own server, 30 days with a hosted version
Time to launch: 2 hours

  • Live Journal

LiveJournal is, at its core, a community collaboration tool that allows you to form networks of “friends” and blogs online. While it’s often used to create simple blogs, the tool isn’t the best in its realm, especially in comparison to some of the free tools (LiveJournal, is about $2 a month). It’s not very intuitive to set up, and the less-than-professional-looking templates are difficult to modify, even with advanced coding skills. If you’re looking for a tool to create an organizational blog, there are better choices.

  • Price:  $4.95/month for Basic, $8.95/month for Plus, or $14.95/month for Pro

  • Hosted or installed?  Hosted

  • Bandwidth:  2GB for Basic, 5GB for Plus, and 10GB for Pro

  • Supports Categories:  Yes

  • Supports Excerpts:  Yes (except for Basic)

  • Supports Post JavaScript:  Yes

  • One Step Pictures:  Yes


Assets & Database hosting on Amazon/S3

Assets Hosting
Lately I was working on a project, highly data driven. Its a movie social network, means there are lots of assets, Photos, Audios & videos. Thats why we should keep continuous backup for our data on some 3rd party provider or somewhere else, which is easier to manage. We are using Amazon::S3 module for our assets and database backup.

Database Backup:

For database backup on S3 we used a ruby gem named “mysql_s3_backup”, a simple backup script for mysql and s3 with incremental backups. Before starting the backups, Create a YAML config file:
# Database name to backup
database: xyz_development
# Mysql user and password to execute commands
user: dbuser
password: paswword
# Path to mysql binaries, like mysql, mysqldump (optional)
bin_path: /usr/bin/
# Path to the binary logs, should match the bin_log option in your my.cnf
bin_log: /var/lib/mysql/binlog/mysql-bin
# S3 bucket name to backup to
bucket: bucketname
# S3 credentials
access_key_id: XXXXXXXXXXXXXXX

Create a full backup:
mysql_s3_backup -c=your_config.yml full
Create an incremental backup:
mysql_s3_backup -c=your_config.yml inc
Restore the latest backup (applying incremental backups):
mysql_s3_backup -c=your_config.yml restore
Restore a specific backup (NOT applying incremental backups):
mysql_s3_backup -c=your_config.yml restore 20091126112233

We were planning to just keep backup for last 5 copies of the database. So, I did a tweak in the code, and written one wrapper class over the GEM for storing only last 5 backups [in case of full backups only].

require 'mysql_s3_backup'

class MysqlS3Dumper
  attr_accessor :config
  class MysqlS3Backup::Backup
    def full(name=make_new_name)
      lock do
        # When the full backup runs it delete any binary log files that might already exist
        # in the bucket. Otherwise the restore will try to restore them even though they’re
        # older than the full backup.
        @bucket.delete_all @bin_log_prefix
        with_temp_file do |file|
          puts file
, file)
          @bucket.copy(dump_file_name(name), dump_file_name("latest"))

  class MysqlS3Backup::Bucket
    def keep_last_five
      puts @name
      puts "coming to bucket"
      all_backups = AWS::S3::Bucket.objects(@name)
      while all_backups.count > 6
        all_backups = AWS::S3::Bucket.objects(@name)

  def initialize
    @config = MysqlS3Backup::Config.from_yaml_file(File.dirname(__FILE__) + "/../config/s3_mysql.yml")


Assets Backup:

For assets backup we use S3Backup ruby gem. S3Backup, is a backup tool to local directory to Amazon S3. It uploads local directory to Amazon S3 with compression. If directories isn’t modified after prior backup,those aren’t upload. It can be Cryptnize upload files if password and salt are configured. To use remotebackup,you should prepare backup configuration file by yaml such below:

bucket: “bucket name”
– “absolute path to directory for backup/restore”
– “iterate directory as you like”
access_key_id: ‘Amazon access_key_id’
secret_access_key: ‘Amazon secret_access_key’
password: ‘password for aes. (optional)’
salt: ‘HexString(16 length) (must when password is specified) ‘
buffer_size: ‘number of byte max 50000000000 (optional default 32000000)’
max_retry_count: ‘number of retry of post if post failed.(optional default 10)’
proxy_host: proxy host address if you use proxy.
proxy_port: proxy port if you use proxy.
proxy_user: login name for proxy server if you use proxy.
proxy_password: login password for proxy server if you use proxy.
log_level: ‘output log level. value is debug or info or warn or error(optional default info)’
temporary: ‘temporary directory path. default(/tmp)
*If directories isn’t specified when restore, it restores all directories in bucket.*

=== backup
s3backup [-f configuration file] [-v verbose message] [-l path for log] [-h help]
configuration file path to file written above contents. default is ./backup.yml
verbose display directory tree and difference of anterior backup
path for log defaut starndard output.
help help message

=== restore
s3backup -r [-f configuration file] [-v verbose message] [-l path for log] [-o output dir] [-h help]
configuration file path to file written above contents. default is ./backup.yml
verbose display directory tree and difference of anterior backup
path for log defaut starndard output.
output dir path to directory for restore directory. defaut is ./
help help message

ImdbCelebrity – A new rubygem for parsing celebritydata from

Last week I was working on my scrapper for getting Imdb Celebrity data for some specific purpose. Then, I searched for some available plugin or gem for the same. More surprisingly I was not able to find something what I’m looking for. Then, one idea stuck in my mind, why not create one of my own. Then I started working on this small rubygem named “imdb_celebrity”. You can see the public repository of the gem on github imdb celebrity. Also gem is hosted on GemCutter as well.

Imdb_celebrity is a ruby-gem which is used for scrapping celebrity pages from . You can install imdb_celebrity as

  gem install imdb_celebrity

With current initial release we can search a celebrity with name or we can fetch content for a celebrity with given IMDB id or/and name, by specifying which parser we want to use. Right now we support Hpricot and Nokogiri as parser classes.


require ‘imdb_celebrity’

** searching a celebrity

imdb_celebs =“Brad Pitt”) imdb_celebs.celebrities

# this will return array of celebrity objects.

Also you can define the ParserClass which u wanna use [ right now you have choice of using either Nokogiri or Hpricot], as

imdb_celebs =“Brad Pitt”, “NokogiriParser”)

#by default it will be HpricotParser imdb_celebs.celebrities

** Fetching data for celebrity celeb =“0000093”, “brad pitt”) # give 7 digit imdbid number


=> it will give you the type of parser class it using


=> will give you the public methods of ImdbCelebrity::Celebrity class only

celeb.to_s => will return an array of celebrity data items containing name, real_name, biography, nationality, height, url.


* Hpricot gem should be installed.

* Nokogiri gem should be installed.

RailsCast’s Crawler – RubyScript

First of all thanks to RyanBates for his valuable contribution towards the rails community with those short and easy-to-understand railscast videos. From Past few months I continuously watching those videos. Yesterday while downloading one of those videos, I realize rather than downloading them when its needed, it better to write some very short & sweet script which will do that for me which giving me any trouble. After looking for some already existing rubyscripts on internet, I ended up writing my own.

require ‘rubygems’
require ‘hpricot’
require ‘open-uri’
class GetRailsCasts
def initialize
def start
1.upto(229){ |eps|
eps_doc = Hpricot(open(“#{@host}#{eps}”)) rescue nil
if eps_doc
# cd to the folder where u want to store the rails-cast videos
`cd /Users/sandy/railscasts; wget #{(eps_doc/”.download/a”).first[:href]}`
Comment are most welcome

Enhancing script/console

I Used Rails ./script/console a lot for debugging my rails apps. Every time when I started debugging something, I have to keep my console log[*.log] file to see what corresponding queries being generated to carried out the result I desired.

I found a better solution for that. I enhanced my script/console, which enabled on-screen query logging for my rails app. I made a small change to #{RAILS_ROOT}/script/console.rb file, which it will look to load any additional ruby file resides in #{RAILS_ROOT}/console_script/ if available.

I have also included the script I wanted to load in the first place, I find it quite handy to be able to see what kind of queries my commands are generating.

#updates /script/console.rb

LOAD_HOOK_DIRECTORY = “#{RAILS_ROOT}/console_scripts”

Find.find( LOAD_HOOK_DIRECTORY ) do |filename|
if filename =~ /\.rb$/
puts “Adding #{filename} to load-path”
libs << ” -r #{filename}”
#add sql_log.rb file to /console_script/
def log_to(stream=STDOUT, colorize=true)
ActiveRecord::Base.logger =
ActiveRecord::Base.colorize_logging = colorize

Black Book Web mail import gem-add mail provider

Black book is one the easiest way to add web email importing feature in your application. Recently I am working on a Social network cum movie portal site. By default, black book provides support for gmail, yahoo, hotmail, AOL and csv. But as per my requirement I have to add 20-30 mail providers from different countries. I started with

require “blackbook”
require “hpricot”
require ‘blackbook/importer/page_scraper’

class Free < Blackbook::Importer::PageScraper
# your code

How to login into the users’ account for which we are fetching contacts.

def login
page = agent.get(‘;)
form = page.form_with(:name => “implogin”)
form.imapuser = options[:username]
form.fields[4].value = options[:password]
page = agent.submit(form,form.buttons.first)
raise( Blackbook::BadCredentialsError, “That username and password was not accepted. Please check them and try again.” ) if page.body =~ /Username and password do not match/

def scrape_contacts
unless agent.cookies.find{|c| == “Horde”}
raise( Blackbook::BadCredentialsError, “Must be authenticated to access contacts.” )

page = agent.get(‘;)
contact_rows = (“form[@name=contacts]”))
data = Hpricot(contact_rows.to_s)
data = (data/”table[1]”)/”.listitem”
data.collect do |row|
:name  => (row/”a”).first.inner_text,
:email => (row/”a”).last.inner_text

Points to keep track

  • scraping contacts differs from one mail provider to another.
  • dependencies- mechanize, faster-csv for page scraping
  • we can extend  the mail provider within the black book gem as well as with in ur app[no need to patch gem]

Rails ActiveRecord – has_and_belongs_to_many & Duplicate entry Error

Scenario :

In One of my project, we had  Many to Many association between models. this allowed me to look more deeply into the has_and_belongs_to_many(HABTM)  association.

When we say:

class Movies < ActiveRecord::Base
has_and_belongs_to_many :gallery_photos, :join_table=> "movies_gallery_photos"

class GalleryPhoto < ActiveRecord::Base
has_and_belongs_to_many :movies, :join_table=>"movies_gallery_photos"

Rails will assume there is a table “movies_gallery_photos” that include foreign keys to the two entities. So this table should be created by the following migration

create_table :movies_gallery_photos, :id => false do |t|
t.integer :movie_id, :null => false
t.integer :gallery_photo_id, :null => false

:id=>false will prevent the creation of the default primary key for that table.

as the API documentation say; other attributes in that relation will be loaded with the objects and will be read only, including the :id. So failing to disable the id generation for that table will cause the loaded objects to have and “id” attribute holding the value of the id or the movies_gallery_photos entries instead of the ids of the target entity (movies or gallery_photos here).

Issue :

Having (:id) false helps to over Mysql::Error: Duplicate entry ‘#’ for key #” entry error we faces while adding entries. (movie.gallery_photos << photo). But it leads to creation and availability of duplicate values in the movies_gallery_photos table. i.e.

movies.gallery_photos << photos

will not check for uniqueness of the photos objects.