Logo

Rotor Maintenance on bikes with disc brakes

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

13-bicycle_disc_brake_rotor-l

Check out the recent post up on Pinkbike’s Tech Tuesday – Rotor Straightening

There are a couple of things we can do regularly to ensure sharp, snappy and spot-on braking.

Tools required
  • Isopropyl Alcohol (maybe ask for Spirit if you get blank stares) or Isopropyl Alcohol swabs – all available at your local chemist
  • Cotton swabs
  • Allen keys – mostly size 4 and 5
  • a Rotor Truing Fork from any brand (or use your hands as shown in the Pinkbike tutorial. We recommend using proper tools and NOT your hands)
Procedure

Step 1: Service the housing

Step 2: Check for wear n tear of the brake pads. If the braking surface is less than an mm thick, replace it.

If the braking surface on the pads is uneven use water proof sandpaper or a fine file to take a thin layer off the brake pads. You could also clean out the pads with the alcohol swabs. This should increase your braking power too.
Check the post on Bike Radar to remore/replace disc brake pads

Step 3: Replace brake cables if you see signs of fraying or rusting. They are cheap to replace and worth it!

Step 4: Clean the Rotors with isopropyl alcohol. Clean out the caliper while you are at it. Get all the gunk out!

Step 5: Insert the brake pads and setup the disc brakes. True the rotor if required – this will not only reduce squealing and ensure better braking but should also increase the life of your brake pads.

If you have a hydraulic system on your bike, you can skip Step 1 and replace it with a hydraulic system bleed the braking feels spongy.

All this should hardly take any time. Especially if done regularly! But it should make a massive difference to your ride and the confidence while braking.

every Monday Bicycling Movie Nite's - How To, Volume 1

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

monday movie nites

Every Monday Bicycling Movie nite – we intend to watch a biking movie every monday evening.
Start around 7:30pm and wrap up in an hour.

Today, 26th September
Time – 7:30pm
WhereBumsOnTheSaddle

We are watching an instructional video on how to tame the trail – 22 MTB handling skills.

1. Why – Monday’s are boring. We want to spice up your life.
2. BYOB event – so BYOB please.
3. Everyone is welcome. Really.

Talk Ruby to a Ruby Class instead of JSON to an HTTP Service

5 months ago | Alex Rothenberg: Common Sense Software

Software as a service (SaaS) is a great thing. I love that other people are providing services and I don’t have to implement them myself. I can use Airbrake for error notifications and even Twitter for communication. It frees me to focus on what’s unique about my app. Its great that they all work with open standards like HTTP, JSON and XML. But what I like even more is not having to think about HTTP, JSON or XML! When writing a Ruby application I want to think about Ruby. The services I really like provide a gem that hides the transport api details and lets me write plain ruby.

If you are creating a service yourself or even using someone else’s service it’s not too hard to create your own client gem. Let’s look at an example how we can do that.

An Example: User Directory Service

Imagine you’re building a user directory that lets you list users, create users, update users, show users, delete users, you know, the standard RESTFUL actions. For instance we could create a user and list all users like this

[~]$ curl -F 'user[name]'='Mickey Mouse' http://user-directory.example.com/users.json
{"user":{"name":"Mickey Mouse","id":1001}}

[~]$ curl http://user-directory.example.com/users.json
[{"user":{"name":"Mickey Mouse","id":1001}}]

This is great to use from CURL but writing the code to talk http form fields and parse json will get pretty tiring. I’d much rather have a UserDirectory::User object that behaved similarly to an ActiveRecord model. When we’re done we want to be able to have it work this

user = UserDirectory::User.create(:name => 'Jenny', :phone => '867-5309')
# => #<UserDirectory::User:0x10239b0b8 @name="Jenny", @phone="867-5309", @id=1001>
user.name
# => 'Jenny'
user.id
# => 1001

UserDirectory::User.all
# => [ #<UserDirectory::User:0x102375638 @name="Jenny", @phone="867-5309", @id=1001>  ]

Building our client gem

We’ll want to wrap this client into a gem so it can be reused by many applications. I prefer to use bundler and its bundle gem command to start my gem. I’ll assume you know how to do that - check out this railscast if you’ve never done it before.

We’re going to get started by building a model class to represent the user without actually connecting it to our service yet.

module UserDirectory
  class User
    include ActiveModel::Validations
    validates_presence_of :name

    attr_accessor :name, :phone
    def initialize(attributes={})
      attributes.each do |name, value|
        send("#{name}=", value)
      end
    end
  end
end

I hope you didn’t think all model classes had to subclass ActiveRecord::Base! For me a model represents a concept in the application domain and does not have to map to a database table!

The magic in here is that we’re mixing in the ActiveModel::Validations module. This lets us add the same validations we would to a “regular” ActiveRecord model - in this case validates_presence_of :name. When Rails 3.0 came along much of the functionality of ActiveRecord was extracted into ActiveModel which lets you make any ruby object feel like ActiveRecord and as with most other topics Ryan Bates has put together a great railscast.

When we try it out it behaves as we expect.

# A valid user
user = UserDirectory::User.new(:name => 'alex')
# => #<UserDirectory::User:0x12b79fff0 @name="alex">
user.valid?
# => true

# an invalid user
user = UserDirectory::User.new(:phone => '555-1212')
# => #<UserDirectory::User:0x12b78ecf0 @phone="555-1212">
user.valid?
# => false
user.errors
# => #<ActiveModel::Errors:0x12b788f80 @base=#<UserDirectory::User:0x12b78ecf0
#      @errors=#<ActiveModel::Errors:0x12b788f80 ...>, @validation_context=nil, @phone="555-1212">,
#      @messages=#<OrderedHash {:name=>["can't be blank"]}>>

The next step is to make our model interact with the service using HTTP and JSON. I’m going to be using the HTTParty gem. It is much easier to use than net/http and automatically parses json or xml into a ruby hash for us.

First, we’ll add a create method that tells the service to create a new user as long as we pass our validations and then returns a User instance.

module UserDirectory
  class User
    # all the existing code and...

    def attributes
      { :name => name, :phone => phone }
    end

    include HTTParty
    base_uri 'http://user-directory.example.com'

    def self.create attributes
      user = new(attributes)
      return user unless user.valid?

      response = post('/users.json', :body => user.attributes)
      raise "#{response.code}: Better error handling please" unless response.success?
      self.new(response.parsed_response)
    end
  end
end

We can do the same for an all method that returns an array of all users stored in the service.

module UserDirectory
  class User
    # all the existing code and...

    def self.all
      response = get('/users.json')
      raise "#{response.code}: Better error handling please" unless response.success?
      response.parsed_response.map do |user_attributes|
        self.new user_attributes
      end
    end
  end
end

Let’s try it out.

# No users yet
UserDirectory::User.all
# => []

# Create a user
UserDirectory::User.create(:name => 'alex', :phone => '555-1212')
# => #<UserDirectory::User:0x12c52f0a8 @name="alex", @phone="555-1212">

# Now ask the service again
UserDirectory::User.all
# => [#<UserDirectory::User:0x12b8890d8 @name="alex", @phone="555-1212">]

This is great! We have a class that’s easy to use, behaves like a normal model but actually talks JSON and HTTP to a remote service. We could continue along the same lines to implement the other methods we need like find & destroy but I’m not going to bore you with that here. Instead I’ll switch gears and talk about building a fake service to eliminate the need to have the actual service running during development and testing.

Building a fake service

There are a few reasons we want to build a fake service.

  1. It’ll be faster to not make any network calls
  2. It’s a lot of overhead to start a local copy of the service during development
  3. It’ll be easier to test various failures (500 errors and the like)
  4. It allows us to setup and clear the data any way we want

How do we create a fake service? Luckily there’s a gem for that! The ShamRack gem intercepts http calls before they leave our app and redirects them to a local Rack App we’ll create. We’ll create a simple sinatra app that implements the UserDirectory Service API and embed it in our gem.

First things first, add the gem to our gem’s user_directory_client.gemspec

gem.add_dependency "sham_rack"

Now we can

require 'sinatra'
require 'sham_rack'

module UserDirectory
  class FakeService < Sinatra::Base

    ###################
    # ShamRack methods
    def self.activate!
      ShamRack.mount(self, "user-directory.example.com", 80)
    end
    def self.deactivate!
      ShamRack.unmount_all
    end


    ###################
    # Sinatra methods
    configure do
      set :raise_errors, true
      set :show_exceptions, false
    end

    USER_JSON = {:name=>'Jenny', :phone=>'867-5309'}.to_json

    get '/users.json' do
      content_type 'text/json'
      [USER_JSON] # :hardcoded list of 1 user
    end

    # :create new user
    post '/users.json' do
      content_type 'text/json'
      USER_JSON # pretend to create and return hardcoded user
    end
  end
end

Its very simple and will always return the same hardcoded user but that might be enough. We turn the fake service on and off with calls to UserDirectory::FakeService.activate! and UserDirectory::FakeService.deactivate!. Let’s take a look.

UserDirectory::FakeService.activate!
# => PeopleServices::FakePeopleService

UserDirectory::User.all
# => [#<UserDirectory::User:0x12c52f0a8 @name="jenny", @phone="867-5309">]

UserDirectory::User.create(:name => 'alex', :phone => '555-1212')
# => #<UserDirectory::User:0x12b8731e8 @name="jenny", @phone="867-5309">
UserDirectory::User.create(:name => 'pat')
# => #<UserDirectory::User:0x12b86cc58 @name="jenny", @phone="867-5309">

UserDirectory::User.all
# => [#<UserDirectory::User:0x12b865cf0 @name="jenny", @phone="867-5309">]

This is interesting. Its fast and eliminates the dependency, but its all hardcoded! When we created 2 users we still got the same “Jenny” user every time. The good news is the fake service is just a class we wrote so we can make is as complex as we need. Perhaps what we have here is enough for you and you’re all done but we’ll assume you want something a bit more realistic.

We’re going to create a quick array to simulate persisting our users.

require 'sinatra'
require 'sham_rack'

module UserDirectory
  class FakeService < Sinatra::Base

    # ShamRack methods ... remain unchanged

    # Sinatra methods ... changed to use our new "business logic"
    get '/users.json' do
      self.class.users.to_json
    end

    post '/users.json' do
      create_user(params)
    end

    ###################
    # Some "business logic"
    # the worlds simplest db :)
    def self.users
      @users ||= []
    end
    def create_user attributes
      attributes['id'] = rand(10000)
      self.class.users << attributes.dup
      attributes.to_json
    end
  end
end

One last time we’re going to try it out.

UserDirectory::FakeService.activate!
# => PeopleServices::FakePeopleService

# We start off empty
UserDirectory::User.all
# => []

# Create some users - the attributes correctly change
UserDirectory::User.create(:name => 'alex', :phone => '555-1212')
# => #<UserDirectory::User:0x12b85f300 @name="alex", @phone="555-1212">
UserDirectory::User.create(:name => 'pat')
# => #<UserDirectory::User:0x12b857880 @name="pat">

# Now we have our 2 users
UserDirectory::User.all
# => [#<UserDirectory::User:0x12b851318 @name="alex", @phone="555-1212">, #<UserDirectory::User:0x12b84adb0 @name="pat">]

This is now looking almost like a real service and will be very useful as we do our development. One last enhancement is that it’ll be nice to test what happens when the service has errors.

require 'sinatra'
require 'sham_rack'

module UserDirectory
  class FakeService < Sinatra::Base
    # Everything else unchanged...

    def self.fail_next_request!
      @fail_next_request = true
    end
    def self.should_fail_request?
      should_fail = @fail_next_request
      @fail_next_request = false
      should_fail
    end

    # Sinatra before filter
    before do
      halt 500, 'We were told to fail!' if self.class.should_fail_request?
    end
  end
end

One last time we’ll try it out.

UserDirectory::FakeService.activate!
# => true
UserDirectory::FakeService.fail_next_request!
# => true
 
UserDirectory::User.create :name => 'Alex'
RuntimeError: 500: We were told to fail!
	from /Users/alex/user_directory_client/lib/user_directory/user.rb:25:in `create'
	from (irb):56

Now go off and create a client for any service you create and be sure to include a fake service!

Talk Ruby to a Ruby Class instead of JSON to an HTTP Service

5 months ago | Alex Rothenberg: Common Sense Software

Software as a service (SaaS) is a great thing. I love that other people are providing services and I don’t have to implement them myself. I can use Airbrake for error notifications and even Twitter for communication. It frees me to focus on what’s unique about my app. Its great that they all work with open standards like HTTP, JSON and XML. But what I like even more is not having to think about HTTP, JSON or XML! When writing a Ruby application I want to think about Ruby. The services I really like provide a gem that hides the transport api details and lets me write plain ruby.

If you are creating a service yourself or even using someone else’s service it’s not too hard to create your own client gem. Let’s look at an example how we can do that.

An Example: User Directory Service

Imagine you’re building a user directory that lets you list users, create users, update users, show users, delete users, you know, the standard RESTFUL actions. For instance we could create a user and list all users like this

[~]$ curl -F 'user[name]'='Mickey Mouse' http://user-directory.example.com/users.json
{"user":{"name":"Mickey Mouse","id":1001}}

[~]$ curl http://user-directory.example.com/users.json
[{"user":{"name":"Mickey Mouse","id":1001}}]

This is great to use from CURL but writing the code to talk http form fields and parse json will get pretty tiring. I’d much rather have a UserDirectory::User object that behaved similarly to an ActiveRecord model. When we’re done we want to be able to have it work this

user = UserDirectory::User.create(:name => 'Jenny', :phone => '867-5309')
# => #<UserDirectory::User:0x10239b0b8 @name="Jenny", @phone="867-5309", @id=1001>
user.name
# => 'Jenny'
user.id
# => 1001

UserDirectory::User.all
# => [ #<UserDirectory::User:0x102375638 @name="Jenny", @phone="867-5309", @id=1001>  ]

Building our client gem

We’ll want to wrap this client into a gem so it can be reused by many applications. I prefer to use bundler and its bundle gem command to start my gem. I’ll assume you know how to do that - check out this railscast if you’ve never done it before.

We’re going to get started by building a model class to represent the user without actually connecting it to our service yet.

module UserDirectory
  class User
    include ActiveModel::Validations
    validates_presence_of :name

    attr_accessor :name, :phone
    def initialize(attributes={})
      attributes.each do |name, value|
        send("#{name}=", value)
      end
    end
  end
end

I hope you didn’t think all model classes had to subclass ActiveRecord::Base! For me a model represents a concept in the application domain and does not have to map to a database table!

The magic in here is that we’re mixing in the ActiveModel::Validations module. This lets us add the same validations we would to a “regular” ActiveRecord model - in this case validates_presence_of :name. When Rails 3.0 came along much of the functionality of ActiveRecord was extracted into ActiveModel which lets you make any ruby object feel like ActiveRecord and as with most other topics Ryan Bates has put together a great railscast.

When we try it out it behaves as we expect.

# A valid user
user = UserDirectory::User.new(:name => 'alex')
# => #<UserDirectory::User:0x12b79fff0 @name="alex">
user.valid?
# => true

# an invalid user
user = UserDirectory::User.new(:phone => '555-1212')
# => #<UserDirectory::User:0x12b78ecf0 @phone="555-1212">
user.valid?
# => false
user.errors
# => #<ActiveModel::Errors:0x12b788f80 @base=#<UserDirectory::User:0x12b78ecf0
#      @errors=#<ActiveModel::Errors:0x12b788f80 ...>, @validation_context=nil, @phone="555-1212">,
#      @messages=#<OrderedHash {:name=>["can't be blank"]}>>

The next step is to make our model interact with the service using HTTP and JSON. I’m going to be using the HTTParty gem. It is much easier to use than net/http and automatically parses json or xml into a ruby hash for us.

First, we’ll add a create method that tells the service to create a new user as long as we pass our validations and then returns a User instance.

module UserDirectory
  class User
    # all the existing code and...

    def attributes
      { :name => name, :phone => phone }
    end

    include HTTParty
    base_uri 'http://user-directory.example.com'

    def self.create attributes
      user = new(attributes)
      return user unless user.valid?

      response = post('/users.json', :body => user.attributes)
      raise "#{response.code}: Better error handling please" unless response.success?
      self.new(response.parsed_response)
    end
  end
end

We can do the same for an all method that returns an array of all users stored in the service.

module UserDirectory
  class User
    # all the existing code and...

    def self.all
      response = get('/users.json')
      raise "#{response.code}: Better error handling please" unless response.success?
      response.parsed_response.map do |user_attributes|
        self.new user_attributes
      end
    end
  end
end

Let’s try it out.

# No users yet
UserDirectory::User.all
# => []

# Create a user
UserDirectory::User.create(:name => 'alex', :phone => '555-1212')
# => #<UserDirectory::User:0x12c52f0a8 @name="alex", @phone="555-1212">

# Now ask the service again
UserDirectory::User.all
# => [#<UserDirectory::User:0x12b8890d8 @name="alex", @phone="555-1212">]

This is great! We have a class that’s easy to use, behaves like a normal model but actually talks JSON and HTTP to a remote service. We could continue along the same lines to implement the other methods we need like find & destroy but I’m not going to bore you with that here. Instead I’ll switch gears and talk about building a fake service to eliminate the need to have the actual service running during development and testing.

Building a fake service

There are a few reasons we want to build a fake service.

  1. It’ll be faster to not make any network calls
  2. It’s a lot of overhead to start a local copy of the service during development
  3. It’ll be easier to test various failures (500 errors and the like)
  4. It allows us to setup and clear the data any way we want

How do we create a fake service? Luckily there’s a gem for that! The ShamRack gem intercepts http calls before they leave our app and redirects them to a local Rack App we’ll create. We’ll create a simple sinatra app that implements the UserDirectory Service API and embed it in our gem.

First things first, add the gem to our gem’s user_directory_client.gemspec

gem.add_dependency "sham_rack"

Now we can

require 'sinatra'
require 'sham_rack'

module UserDirectory
  class FakeService < Sinatra::Base

    ###################
    # ShamRack methods
    def self.activate!
      ShamRack.mount(self, "user-directory.example.com", 80)
    end
    def self.deactivate!
      ShamRack.unmount_all
    end


    ###################
    # Sinatra methods
    configure do
      set :raise_errors, true
      set :show_exceptions, false
    end

    USER_JSON = {:name=>'Jenny', :phone=>'867-5309'}.to_json

    get '/users.json' do
      content_type 'text/json'
      [USER_JSON] # :hardcoded list of 1 user
    end

    # :create new user
    post '/users.json' do
      content_type 'text/json'
      USER_JSON # pretend to create and return hardcoded user
    end
  end
end

Its very simple and will always return the same hardcoded user but that might be enough. We turn the fake service on and off with calls to UserDirectory::FakeService.activate! and UserDirectory::FakeService.deactivate!. Let’s take a look.

UserDirectory::FakeService.activate!
# => PeopleServices::FakePeopleService

UserDirectory::User.all
# => [#<UserDirectory::User:0x12c52f0a8 @name="jenny", @phone="867-5309">]

UserDirectory::User.create(:name => 'alex', :phone => '555-1212')
# => #<UserDirectory::User:0x12b8731e8 @name="jenny", @phone="867-5309">
UserDirectory::User.create(:name => 'pat')
# => #<UserDirectory::User:0x12b86cc58 @name="jenny", @phone="867-5309">

UserDirectory::User.all
# => [#<UserDirectory::User:0x12b865cf0 @name="jenny", @phone="867-5309">]

This is interesting. Its fast and eliminates the dependency, but its all hardcoded! When we created 2 users we still got the same “Jenny” user every time. The good news is the fake service is just a class we wrote so we can make is as complex as we need. Perhaps what we have here is enough for you and you’re all done but we’ll assume you want something a bit more realistic.

We’re going to create a quick array to simulate persisting our users.

require 'sinatra'
require 'sham_rack'

module UserDirectory
  class FakeService < Sinatra::Base

    # ShamRack methods ... remain unchanged

    # Sinatra methods ... changed to use our new "business logic"
    get '/users.json' do
      self.class.users.to_json
    end

    post '/users.json' do
      create_user(params)
    end

    ###################
    # Some "business logic"
    # the worlds simplest db :)
    def self.users
      @users ||= []
    end
    def create_user attributes
      attributes['id'] = rand(10000)
      self.class.users << attributes.dup
      attributes.to_json
    end
  end
end

One last time we’re going to try it out.

UserDirectory::FakeService.activate!
# => PeopleServices::FakePeopleService

# We start off empty
UserDirectory::User.all
# => []

# Create some users - the attributes correctly change
UserDirectory::User.create(:name => 'alex', :phone => '555-1212')
# => #<UserDirectory::User:0x12b85f300 @name="alex", @phone="555-1212">
UserDirectory::User.create(:name => 'pat')
# => #<UserDirectory::User:0x12b857880 @name="pat">

# Now we have our 2 users
UserDirectory::User.all
# => [#<UserDirectory::User:0x12b851318 @name="alex", @phone="555-1212">, #<UserDirectory::User:0x12b84adb0 @name="pat">]

This is now looking almost like a real service and will be very useful as we do our development. One last enhancement is that it’ll be nice to test what happens when the service has errors.

require 'sinatra'
require 'sham_rack'

module UserDirectory
  class FakeService < Sinatra::Base
    # Everything else unchanged...

    def self.fail_next_request!
      @fail_next_request = true
    end
    def self.should_fail_request?
      should_fail = @fail_next_request
      @fail_next_request = false
      should_fail
    end

    # Sinatra before filter
    before do
      halt 500, 'We were told to fail!' if self.class.should_fail_request?
    end
  end
end

One last time we’ll try it out.

UserDirectory::FakeService.activate!
# => true
UserDirectory::FakeService.fail_next_request!
# => true
 
UserDirectory::User.create :name => 'Alex'
RuntimeError: 500: We were told to fail!
	from /Users/alex/user_directory_client/lib/user_directory/user.rb:25:in `create'
	from (irb):56

Now go off and create a client for any service you create and be sure to include a fake service!

Good to know about Indian coins

5 months ago | Niranjan Sarade: InLoveWithNature

I read this information about Indian coins in one Consumer magazine.
Indian coins are mainly produced in four cities:- Delhi,Mumbai, Hyderabad and Kolkata. The production in city puts an identification mark under the year of issue. Coins produced in:
1. Delhi - have a dot
2. Mumbai - have a diamond
3. Hyderabad - have a star
4. Kolkata - nothing beneath the year.

http://www.oceanofweb.com/interesting/facts-indian-coins.html

The PBP Meetup

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

<object height='300' width='400'> <param></param> <param></param> <param></param><embed src='http://www.flickr.com/apps/slideshow/show.swf?v=107931' height='300' width='400'></embed></object>

The Randonneuring Meetup was fun :)

How does Bundler bundle?

5 months ago | Pat Shaughnessy: Pat Shaughnessy - Home

Every time you start a new Ruby project, probably one of the first things you do is write a Gemfile and then run bundle install. Bundler has truly made all of our lives much easier… we know it will install the proper version of all the gems we need. But how does it actually work? This week I decided to take a closer look at the Bundler code itself to find out. How does it know which gems to install? How does it guarantee each gem’s dependencies will be satisfied? How do I get just the right “bundle” my app needs?

Randonneuring Special - PBP Movie nite

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

BOTS movie nite - PBP special
Bikers from Bangalore who took part in the Paris-Brest-Paris 2011

What: Movie nite – PBP: The incredible journey
Where: BumsOnTheSaddle
What time: meetup at 6:30pm
Signup: on the facebook event page, if you like

The usual BOTS Movie nite fundas – get your friends, everyone is welcome, more the merrier and BYOB of course ;)

It all started with a call from one lone biker, Venkatachalam – “How about conducting some long distance rides in Bangalore ? Maybe give the PBP a shot ?

And it culminated with 5 bikers from Bangalore having an ride of their life at the phenomenal 1200Km Paris-Brest-Paris ride

There is a lot that happened in between and a bunch of stars which made it all happen – lots n lots of planning and riding, a good dash of exciting stories and some really really hard work. Game changers!

A big shout out to everyone who put in work to make this happen. There are just too many to talk about here.

The 5 folks who rode the PBP this year

  • Alex
  • Amol
  • Samim
  • Shreyas
  • Venkat

We would be meeting up this Saturday at 6:30pm – all the folks who helped conduct the Bangalore Brevets, the 5 riders who rode the 1200Kms and you of course.

We will also be playing the Paris-Brest-Paris: The Incredible Journey to get an idea of how the 2007 ride went and watch snaps taken by the folks at the PBP

Wanna know more ?

DIY awesome cycling key chain

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

bicycle keychain

Simple.
All you need is some cable ties and some chain links from your chain ;)

Behavioral research

5 months ago | Prasoon Sharma: Enterprise Software Does not Have to Suck


I'm at the O'Reilly's Strata conference in NYC, where a NYU professor shared his research on consumer purchasing behavior. He asserts that 'What people "say" is different from what they actually "do"', so he recommends conducting behavioral studies by measuring what people "do", not what they "say". 

He used camera buying from Amazon as an example, where Zoom is talked about a lot as a feature but has lower impact on purchasing behavior. Whereas Battery Life and Megapixels are talked about less but have higher impact on purchasing behavior. 

Very interesting. 

We often conduct such analysis using surveys in enterprises. To do what he suggests will be more accurate but will cost more... it is much more costly to follow what people "do".


every Monday Bicycling Movie Nite's - Pink Bike Monday Movies

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

Monday Movies

Every Monday Bicycling Movie nite – we intend to watch a biking movie every monday evening. Start around 7:30pm and wrap up in an hour.

  • Starting this Monday – 19th September
  • Time – 7:30pm
  • WhereBumsOnTheSaddle

We are watching a selection of movies from Pink Bike this Monday

1. Why – Monday’s are boring. We want to spice up your life.
2. BYOB event – so BYOB please.
3. Everyone is welcome. Really.

Building JS Org Chart

5 months ago | Amit Kumar: RubyizednRailified


Just released code to create inverted Organization Chart --> library here





Bundler’s Best Kept Secret

5 months ago | Pat Shaughnessy: Pat Shaughnessy - Home

Part of a gem dependency network graph

This week I just discovered Bundler’s best kept secret: the bundle viz command will generate a network graph showing the dependencies among all the different gems used by your Ruby app. For example, the image on the left is a portion of the gem dependency graph for a vanilla Rails 3.1 app. Click here to see the entire, uncropped dependency graph. The gems actually called out in your Gemfile are displayed in grey, while other gems included through dependencies only are shown in white. Finally gem groups are shown as rectangles along the top…

BBCh #8 | Cyclocross race | 18 Sept

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

crossrac
BBCh #8 is all about introducing Cyclocross to Bangalore.

Important Race info

  • When – Sunday, 18 Sept 2011
  • Race CategoryCyclocross
  • Start Time – 7:30am meetup to race at 8am sharp
  • Wherecheck out the map below
  • Who – Anybody and everybody (get friends and family to cheer you along)

Map to race start

BBCh race route

Helmet are mandatory. No excuses.

Race details

We race for 45mins and at the indication of the completion of the time, we race the last lap.

Useful links

Running a Private GemServer inside the Firewall

5 months ago | Alex Rothenberg: Common Sense Software

rubygems.org has made it so easy to publish a gem for the world to use but what do you do when your gem is proprietary and you only want to publish it within your company?

This is something I’ve just been through at my company and thought I’d share the steps I went through. We need to

  1. Setup an inside-the-firewall gem server
  2. Configure our gems to deploy to it
  3. Configure our apps to use it

Setup an inside-the-firewall gem server

The first thing you have to decide is what gemserver to use. Rubygems.org has a helpful page called running your own gemserver that basically lists 3 choices in a goldilocks situation.

  1. too small - gem server is a command built into rubygems

    This works but you need to log onto the server to install a new gem and it serves all gems on the system not just your proprietary ones

  2. too big - rubygems.org is open source so we could deploy it on our own server

    This seems pretty complex to setup and even they tell you to “consider checking out Geminabox”

  3. just right - gem in a box is a simple sinatra app to allow you to host your own in-house gems

    This is easy to setup, has a web interface and supports a command line to remotely publish new gems.

geminabox is what I decided to go with.

The readme on github describes the server setup for geminabox and it just worked. The only thing to keep in mind is that you cannot use bundler as then you will only serve the gems in the bundle instead of the gems you publish. I spent some time adding bundler before realizing that was a bad idea and backing it out.

Once geminabox is up and running you can view your gems at your internal url and you’ll see the gem server homepage showing you it has no gems.

New Gem Server

The easiest thing is to add a new gem by clicking “Upload Another Gem” and selecting a .gem file from your hard drive (I picked diagnostics-0.0.1.gem in the image below).

Upload A Gem Manuallly

Once you click uppload you should see your gem on the page.

Gem Server With A Gem

At this point we could start using this gem server in our apps but before we talk about that let’s automate the manual process we just went through to add a gem.

Configure our gems to deploy to the gem server

I’ve been using bundler to create my gems with the bundle gem command and one of the features that gives you is a set of nice rake tasks. Check out the New Gem with Bundler Railscast to learn how it works.

$ bundle gem my_awesome_gem
      create  my_awesome_gem/Gemfile
      create  my_awesome_gem/Rakefile
      create  my_awesome_gem/.gitignore
      create  my_awesome_gem/my_awesome_gem.gemspec
      create  my_awesome_gem/lib/my_awesome_gem.rb
      create  my_awesome_gem/lib/my_awesome_gem/version.rb
Initializating git repo in /Users/alex/my_awesome_gem

Let’s look at the tasks we’ve got.

$ cd my_awesome_gem
$ rake -T
rake build    # Build my_awesome_gem-0.0.1.gem into the pkg directory
rake install  # Build and install my_awesome_gem-0.0.1.gem into system gems
rake release  # Create tag v0.0.1 and build and push my_awesome_gem-0.0.1.gem to Rubygems

rake build and rake install do their work locally but rake release is what you call when you’re done and ready to release your gem into the wild. This task will push your changes to github, create a git tag, build your gem package and deploy it to http://rubygems.org. We need to do something to change that last part so it deploys to our private gem server instead of rubygems.org.

Let’s spend some time looking into bundler to figure out how rake release works. The magic all happens inside a file lib/bundler/gem_helper.rb

  • It defines a :release rake task
  • Which calls release_gem
  • Which calls rubygem_push
  • Finally this will call gem push pkg/my_awesome_gem-0.0.1.gem which pushes to http://rubygems.org. We’ve found the behavior we need to change.

geminabox adds a custom rubygems command called inabox so you can deploy a gem with the command gem inabox pkg/my-awesome-gem-1.0.gem. Unfortunately bundler does not seem to have a convenient way to change this so we’re going to monkey patch bundler Bundler::GemHelper#rugygem_push method to use the geminabox command instead. (please let me know if you have a better idea)

We’ll add our monkey patch to our Rakefile since its called by a rake command.

# Rakefile in your my_awesome_gem gem

# Monkey patch Bundler gem_helper so we release to our gem server instead of rubygems.org
module Bundler
  class GemHelper
    def rubygem_push(path)
      gem_server_url = 'http://gems.intranet.mycompany.com'
      sh("gem inabox '#{path}' --host #{gem_server_url}")
      Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_server_url}"
    end
  end
end

You can see this will call gem inabox ... so we also need to add geminabox to our gem’s bundle. We do this in the .gemspec as a development dependency

# my_awesome_gem.gemspec in your gem

Gem::Specification.new do |s|
  .. lots of other stuff ...

  s.add_development_dependency "geminabox"
end

Now when we call rake release it will push the gem to our private server instead of the public one. Let’s see:

$ rake release
my_awesome_gem 0.0.1 built to pkg/my_awesome_gem-0.0.1.gem
Tagged v0.0.1
Pushed git commits and tags
Pushed my_awesome_gem 0.0.1 to http://gems.intranet.mycompany.com

Now when we go to the gem server site, we can see our new awesome gem in the list

Gem Server With Awesome Gem

The gem is there an you can use install it with a command like gem install my_awesome_gem --source http://gems.intranet.mycompany.com

Using your Gem Server from an application

We’ve just seen how we can use the source option to tell rubygems where to look when installing our gem by hand, but in a modern application we all use bundler and a Gemfile to manage our gems so how do we tell bundler to user our private gemserver for our private gems? Its super simple, you just need to add a source to the top of your Gemfile

source "http://gems.intranet.mycompany.com/"
source :rubygems

# regular old gems come from rubygems.org
gem "rails"
gem "rack"
gem "haml"

# my private gem comes from my private gemserver
gem 'diagnostics'

Now when we run bundle it looks in our private gem server as well as the public rubygems.org. Now that that you’ve got my_awesoem_gem you’re ready to add awesomeness to your app.

$ bundle
Fetching source index for http://gems.intranet.mycompany.com/
Fetching source index for http://rubygems.org/
Using rake (0.9.2)
Using activesupport (3.1.0)
Installing my_awesome_gem (0.0.1)
...etc..

Running a Private GemServer inside the Firewall

5 months ago | Alex Rothenberg: Common Sense Software

rubygems.org has made it so easy to publish a gem for the world to use but what do you do when your gem is proprietary and you only want to publish it within your company?

This is something I’ve just been through at my company and thought I’d share the steps I went through. We need to

  1. Setup an inside-the-firewall gem server
  2. Configure our gems to deploy to it
  3. Configure our apps to use it

Setup an inside-the-firewall gem server

The first thing you have to decide is what gemserver to use. Rubygems.org has a helpful page called running your own gemserver that basically lists 3 choices in a goldilocks situation.

  1. too small - gem server is a command built into rubygems

    This works but you need to log onto the server to install a new gem and it serves all gems on the system not just your proprietary ones

  2. too big - rubygems.org is open source so we could deploy it on our own server

    This seems pretty complex to setup and even they tell you to “consider checking out Geminabox”

  3. just right - gem in a box is a simple sinatra app to allow you to host your own in-house gems

    This is easy to setup, has a web interface and supports a command line to remotely publish new gems.

geminabox is what I decided to go with.

The readme on github describes the server setup for geminabox and it just worked. The only thing to keep in mind is that you cannot use bundler as then you will only serve the gems in the bundle instead of the gems you publish. I spent some time adding bundler before realizing that was a bad idea and backing it out.

Once geminabox is up and running you can view your gems at your internal url and you’ll see the gem server homepage showing you it has no gems.

New Gem Server

The easiest thing is to add a new gem by clicking “Upload Another Gem” and selecting a .gem file from your hard drive (I picked diagnostics-0.0.1.gem in the image below).

Upload A Gem Manuallly

Once you click uppload you should see your gem on the page.

Gem Server With A Gem

At this point we could start using this gem server in our apps but before we talk about that let’s automate the manual process we just went through to add a gem.

Configure our gems to deploy to the gem server

I’ve been using bundler to create my gems with the bundle gem command and one of the features that gives you is a set of nice rake tasks. Check out the New Gem with Bundler Railscast to learn how it works.

$ bundle gem my_awesome_gem
      create  my_awesome_gem/Gemfile
      create  my_awesome_gem/Rakefile
      create  my_awesome_gem/.gitignore
      create  my_awesome_gem/my_awesome_gem.gemspec
      create  my_awesome_gem/lib/my_awesome_gem.rb
      create  my_awesome_gem/lib/my_awesome_gem/version.rb
Initializating git repo in /Users/alex/my_awesome_gem

Let’s look at the tasks we’ve got.

$ cd my_awesome_gem
$ rake -T
rake build    # Build my_awesome_gem-0.0.1.gem into the pkg directory
rake install  # Build and install my_awesome_gem-0.0.1.gem into system gems
rake release  # Create tag v0.0.1 and build and push my_awesome_gem-0.0.1.gem to Rubygems

rake build and rake install do their work locally but rake release is what you call when you’re done and ready to release your gem into the wild. This task will push your changes to github, create a git tag, build your gem package and deploy it to http://rubygems.org. We need to do something to change that last part so it deploys to our private gem server instead of rubygems.org.

Let’s spend some time looking into bundler to figure out how rake release works. The magic all happens inside a file lib/bundler/gem_helper.rb

  • It defines a :release rake task
  • Which calls release_gem
  • Which calls rubygem_push
  • Finally this will call gem push pkg/my_awesome_gem-0.0.1.gem which pushes to http://rubygems.org. We’ve found the behavior we need to change.

geminabox adds a custom rubygems command called inabox so you can deploy a gem with the command gem inabox pkg/my-awesome-gem-1.0.gem. Unfortunately bundler does not seem to have a convenient way to change this so we’re going to monkey patch bundler Bundler::GemHelper#rugygem_push method to use the geminabox command instead. (please let me know if you have a better idea)

We’ll add our monkey patch to our Rakefile since its called by a rake command.

# Rakefile in your my_awesome_gem gem

# Monkey patch Bundler gem_helper so we release to our gem server instead of rubygems.org
module Bundler
  class GemHelper
    def rubygem_push(path)
      gem_server_url = 'http://gems.intranet.mycompany.com'
      sh("gem inabox '#{path}' --host #{gem_server_url}")
      Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_server_url}"
    end
  end
end

You can see this will call gem inabox ... so we also need to add geminabox to our gem’s bundle. We do this in the .gemspec as a development dependency

# my_awesome_gem.gemspec in your gem

Gem::Specification.new do |s|
  .. lots of other stuff ...

  s.add_development_dependency "geminabox"
end

Now when we call rake release it will push the gem to our private server instead of the public one. Let’s see:

$ rake release
my_awesome_gem 0.0.1 built to pkg/my_awesome_gem-0.0.1.gem
Tagged v0.0.1
Pushed git commits and tags
Pushed my_awesome_gem 0.0.1 to http://gems.intranet.mycompany.com

Now when we go to the gem server site, we can see our new awesome gem in the list

Gem Server With Awesome Gem

The gem is there an you can use install it with a command like gem install my_awesome_gem --source http://gems.intranet.mycompany.com

Using your Gem Server from an application

We’ve just seen how we can use the source option to tell rubygems where to look when installing our gem by hand, but in a modern application we all use bundler and a Gemfile to manage our gems so how do we tell bundler to user our private gemserver for our private gems? Its super simple, you just need to add a source to the top of your Gemfile

source "http://gems.intranet.mycompany.com/"
source :rubygems

# regular old gems come from rubygems.org
gem "rails"
gem "rack"
gem "haml"

# my private gem comes from my private gemserver
gem 'diagnostics'

Now when we run bundle it looks in our private gem server as well as the public rubygems.org. Now that that you’ve got my_awesoem_gem you’re ready to add awesomeness to your app.

$ bundle
Fetching source index for http://gems.intranet.mycompany.com/
Fetching source index for http://rubygems.org/
Using rake (0.9.2)
Using activesupport (3.1.0)
Installing my_awesome_gem (0.0.1)
...etc..

BOTS Currency - bicycling gift vouchers

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

BOTS Gift vouchers

Ever wanted to gift a biker some bicycling related item and not sure what to gift them ?
How about some BOTS Currency ?

Ringing out the summer.

5 months ago | Queenie Takes Manhattan: Queenie Takes Manhattan

My friend Richard is an all-around fabulous person. He lives a glittering life, full of fashion and fundraising and other sparkly things. He also, as it happens, makes a mean corn salad.

When we headed to Abby & Jason's apartment for dinner a few weeks ago (Abby is Richard's sister; Jason is my cousin.), I contributed a peach-blueberry pie, and Richard brought this incredible salad. It was so simple, but so good. He mixed together raw, sweet corn, red onion, feta, avocado and - though he left a bit out of mine, knowing how I feel about it - cilantro.

I couldn't believe how creamy and salty and sweet the whole thing was. It went beautifully with the steak and potatoes Abby and Jason served, and it was just such a perfect dish for the end of summer. You know how it is - we're coming to the end of the bounty of ridiculously delicious summer produce, and you just want as much of it as you can get.

The version I made at home featured basil instead of cilantro (obviously), and mascarpone instead of feta, since that was what I had. I haven't written up a recipe for it yet - though hopefully I'll be able to soon: I have two precious ears of local New York corn waiting in the fridge.

every Monday Bicycling Movie Nite's - Pink Bike Monday Movies

5 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

Monday Movies

Every Monday Bicycling Movie nite – we intend to watch a biking movie every monday evening. Start around 7:30pm and wrap up in about 45 mins.

  • Starting this Monday – 12th September
  • Time – 7:30pm
  • WhereBumsOnTheSaddle

We are watching a selection of movies from Pink Bike this Monday

1. Why – Monday’s are boring. We want to spice up your life.
2. BYOB event – so BYOB please.
3. Everyone is welcome. Really.

Easy does it.

5 months ago | Queenie Takes Manhattan: Queenie Takes Manhattan

Sometimes, you just need a really simple salad. Last week was just such a time. I was overwhelmed at work, busy and home, and generally a bit wiped out. Cooking anything with a measure of complexity was simply beyond my means, and so I turned to one of the simplest standbys I know.

Sliced tomatoes (heirloom or otherwise; just make sure they're tasty and not bland), sliced red onion, torn basil, good balsamic vinegar (it should be a bit syrupy and rich and a bit sweet, not runny and tangy) and sea salt.

It satisfies the tummy and the soul.

Rails upgrade from 2.3.5 to 3.0.9

5 months ago | Gourav Tiwari: easy_software = Agile.find(ruby_on_rails)

Few weeks back I did rails upgrade for my current project from rails 2.3.5 to rails 3.0.9 (on Windows 7).

I began with rails 3 upgrade guide. So, first step was to install ruby 187, which I already had on my system with pik

There is a good series on rails on upgrading to rails 3 from Ryan Bates:
http://asciicasts.com/episodes/226-upgrading-to-rails-3-part-1
http://asciicasts.com/episodes/226-upgrading-to-rails-3-part-2
http://asciicasts.com/episodes/226-upgrading-to-rails-3-part-3

Some how the rails-upgrade-plugin did not work for me (as I was working on Windows 7) .

I then followed the-path-to-rails-3-approaching-the-upgrade step-by-step and I got application 80% upgraded, the rest 20% was a tough part.

In this blog, I am writing about challenges I faced in this process.


  • Installing rails 3.0.9 gem:
    Somehow gem install rails shown errors:
    C:\myapp>gem install rails
    Successfully installed rails-3.0.9
    1 gem installed

    Installing ri documentation for rails-3.0.9...
    file 'lib' not found
    Installing RDoc documentation for rails-3.0.9...
    file 'lib' not found

    I used,
    C:\myapp>gem install rails --no-rdoc --no-riSuccessfully installed rails-3.0.9
    1 gem installed
  • routes.rb
    I had to update the routes.rb file and I found one really helpful link: http://stackoverflow.com/questions/3103765/routing-in-rails-3-map-with-options
  • Deprecation warning for cookie_store:
    DEPRECATION WARNING: ActionController::Base.session= is deprecated. Please configure it on your application with config.session_store :cookie_store, :key => '....'. (called from C:/myapp/config/initializers/session_store.rb:7)

    So, I did:
    module Myapp  class Application < Rails::Application    config.session_store :cookie_store, :key => '_myapp_session', :secret => 'some-secret-string-very-long'
    Also, I removed C:/myapp/config/initializers/session_store.rb file.
    Reference: http://stackoverflow.com/questions/3720379/sqlsessionstore-in-rails-3 and http://apidock.com/rails/ActiveRecord/SessionStore
  • Logging the deprecation warnings
    I saw another warning:
    You did not specify how you would like Rails to report deprecation notices for your development environment, please set config.active_support.deprecation to :log at config/environments/development.rb

    So, I updated development.rb (and other .rb files):
    Myapp::Application.configure do    config.active_support.deprecation = :log
  • consider_all_requests_local warning
    DEPRECATION WARNING: ActionController::Base.consider_all_requests_local= is deprecated. Please configure it on your application with config.consider_all_requests_local=.

    So, I added this snippet in config/environments/development.rb
    Myapp::Application.configure do config.consider_all_requests_local = true
  • Some easy once
    1. DEPRECATION WARNING: RAILS_ENV is deprecated. Please use ::Rails.env.
    So, wherever I was using RAILS_ENV, I replaced with Rails.env

    2. DEPRECATION WARNING: RAILS_ROOT is deprecated. Please use ::Rails.root.to_s.
    So, wherever I was using RAILS_ROOT, I replaced with Rails.root.to_s
  • ActionMailer warnings
    1. When you need to set character set for action mailer, you specify in initializer.rb, which throws this warning:
    DEPRECATION WARNING: ActionMailer::Base.default_charset=value is deprecated, use default :charset => value instead

    I passed hash to the default method in application.rb:
    Myapp::Application.configure do default :charset => 'utf-8'
    2 Similarly the mime version we set in initializers:
    DEPRECATION WARNING: ActionMailer::Base.default_mime_version=value is deprecated, use default :mime_version => value instead.

    I passed hash to the default method in application.rb:
    Myapp::Application.configure do default :mime_version => '1.0'

    3. For multipart emails the setting has to be adjusted:
    DEPRECATION WARNING: ActionMailer::Base.default_implicit_parts_order=value is deprecated, use default :implicit_parts_order => value instead
    This is again can be passed to default method:
    Myapp::Application.configure do   default :parts_order => [ "text/plain", "text/enriched", "text/html" ]
  • html_safe in view?
    For 2-3 hours I struggled to find the reason, why the select tag was not producing the tags. When I found it I understand that this is again a security addition to convert strings into html safe form. So, all your '&lt;' will be converted to '<' and all '&gt;' will be converted into '>'. I actually added .html_safe at the end of each string in view and that showed all the tags finally.

    Reference: rails-3-select-tag-not-producing-dom-elements
  • Removed config.action_view.cache_template_loading, use config.cache_classes instead
    Reference: https://github.com/rails/rails/commit/83e29b9773ac113ceacb1e36c2f333d692de2573
  • Rspec
    I was using rspec and here is the deprecation warning I got:
    *****************************************************************
    DEPRECATION WARNING: you are using a deprecated constant that will be removed from a future version of RSpec.
    C:/cit/spec/controllers/activity_logs_controller_spec.rb:1:in `require'
    * Spec is deprecated.
    * RSpec is the new top-level module in RSpec-2
    ***************************************************************
    ***************************************************************
    DEPRECATION WARNING: you are using deprecated behaviour that will be removed from a future version of RSpec.
    C:/cit/spec/spec_helper.rb:17
    * Spec::Runner.configure is deprecated.
    * please use RSpec.configure instead.

    So, I have to use rspec-rails-2 which supports rails 3.
    Reference: http://groups.google.com/group/cukes/browse_thread/thread/40c4c2aea1c07afe/cb63eb7f0b733646?lnk=raot
  • Ajax stopped working
    I was using jQuery as javascript library, and I found somehow the ajax calls stopped working after the upgrade. I later found that there is a security threat and a fix for that is available
    Here is what I had to do:

    Step#1. In application.html.erb, I had to include csrf_meta_tag:
    <%= javascript_include_tag :defaults %><%= csrf_meta_tag %>
    Step#2. I added this snippet to application.js:
    $(document).ajaxSend(function(e, xhr, options) {  var token = $("meta[name='csrf-token']").attr("content");
    xhr.setRequestHeader("X-CSRF-Token", token);});


    Reference: csrf-protection-bypass-in-ruby-on-rails
  • RackBaseURI instead of RailsBaseURI
    I was using RailsBaseURI in apache, but after upgrade to Rails 3, I had to update it to RackBaseURI
    Reference: RackBaseURI
  • Last but not least, I was using valid? method in helper to check if the object is valid or not and based on that I was displaying certain fields, which was working fine in Rails 2.  In Rails 3 valid? method will trigger validations as well, which caused field_with_errors div to show-up all the time (even when the validation should not happen). I changed the logic to not use valid? method to display other fields and it solved the problem.

Submit a patch for Rails on Github using “fork and edit button”

6 months ago | Arun Agrawal: Ruby Rockers

Hi Folks, I have recently written about my Rails Contributions experience here. I see that now days contribution is Rails is increased. People love to contribute in Open Source projects. And the way should be easy not painful. I found that some people are struggling in submitting Pull Requests in Rails on Github. So i thought [...]

installing mysql gem on ubuntu + ERROR: Error installing mysql

6 months ago | Manohar Amrutkar: majestic rails

If you are facing below issue while installing mysql gem on ubuntu then you need to install 'libmysqlclient-dev' library.

manohar@manohar-Inspiron-1525:~$ gem install mysql
Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
    ERROR: Failed to build gem native extension.

        /home/manohar/.rvm/rubies/ruby-1.9.2-p290/bin/ruby extconf.rb
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lmygcc... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/home/manohar/.rvm/rubies/ruby-1.9.2-p290/bin/ruby
    --with-mysql-config
    --without-mysql-config
    --with-mysql-dir
    --without-mysql-dir
    --with-mysql-include
    --without-mysql-include=${mysql-dir}/include
    --with-mysql-lib
    --without-mysql-lib=${mysql-dir}/lib
    --with-mysqlclientlib
    --without-mysqlclientlib
    --with-mlib
    --without-mlib
    --with-mysqlclientlib
    --without-mysqlclientlib
    --with-zlib
    --without-zlib
    --with-mysqlclientlib
    --without-mysqlclientlib
    --with-socketlib
    --without-socketlib
    --with-mysqlclientlib
    --without-mysqlclientlib
    --with-nsllib
    --without-nsllib
    --with-mysqlclientlib
    --without-mysqlclientlib
    --with-mygcclib
    --without-mygcclib
    --with-mysqlclientlib
    --without-mysqlclientlib

Use below command to resolve above issue-

manohar@manohar-Inspiron-1525:~$ sudo apt-get install libmysqlclient-dev

How does Kaminari paginate?

6 months ago | Pat Shaughnessy: Pat Shaughnessy - Home

“Kaminari” means thunder in Japanese

Kaminari is a popular new gem that provides pagination behavior – to learn how to use it see the Railscast Pagination with Kaminari, or just refer to the Github readme page. For me Kaminari is a good example of “Rails magic…” somehow by just adding the gem to my Rails application all of my models get the Kaminari page method. I don’t have even have to type a single line of code in my model… it’s just automatically added for me. Then when I call page, it immediately works: returning just the records for a given page, even working in conjunction with other scopes I might have…

Looking to hire data scientists

6 months ago | Prasoon Sharma: Enterprise Software Does not Have to Suck

We are a global management consulting firm and are looking for data scientists in our team in New York/Washington DC and Gurgaon/Chennai (India). There are full-time and internship (New York) opportunities. There are multiple positions including developing complex models in healthcare, pricing and optimization. If interested, drop me an email at prasoonsharma at gmail dot com.


Position specifications
- Public contributions (projects, plugins, blogs, open source etc.) on MATLAB, SAS, R, SPSS, Stata a plus
- Significant experience in economic and/or scientific programming. Ideally, experience in popular statistical softwares like MATLAB, SAS, R, SPSS, Stata
- Ability to use, analyze and visualize large data sets
- Demonstrated ability for conceptual analytics including translating design considerations into programmed code
- B.A. required, advanced degree preferred (M.A. or Ph.D. in Computer Science, Applied Science, Engineering, Economics, Statistics or similar)


Position responsibilities
Running and developing complex healthcare models; e.g., behavioral simulation. Specific responsibilities include:
- Maintaining and developing model and other analytic assets
- Driving individual and team problem solving regarding model architecture and continued development of model and related analytic assets (e.g., ability to independently develop hypotheses, approaches and solutions to development objectives)
- Conducting research and analyzing existing data sources to derive solutions and analyses for model development including complex, multi-variate analytical analyses
- Overseeing and writing communication materials supporting analytic materials, including communication decks for clients and for client teams
- Rigorously reviewing and testing of all programmed code to ensure accuracy/veracity of toolkit development
- Working with teams to understand, guide and refine client teams requests
- Developing and maintaining work plans etc.


Got interviewed by Jochen Krebs in the latest Agile NYC Podcast

6 months ago | Nirmal Merchant: Urban Gypsy

My colleague Zainab and I will be presenting in the Pecha Kucha sessions at Agile Day 2011 Conference on 27th September, 2011.  Hear our thoughts and experiences with Agile as we share them in a conversation with Jochen Krebs - Founder of Agile NYC in the latest Agile NYC podcast.

Also check out the very impressive lineup of speakers for the conference (Amy Goodman and Linda Rising are key-note speakers).  There are limited seats available, so register soon if you are interested in attending the conference.

SAP BusinessObjects Dashboards 4.0 Cookbook review

6 months ago | Bhargav Gandhi: AGILE SOFTWARE DEVELOPMENT

I was recently asked by Packt Publishing to review Xavier Hacking and David Lai “SAP BusinessObjects Dashboards 4.0 Cookbook”. I just finished reading the book, and wanted to share some thoughts.

The book’s 10 main chapters successfully provide “Over 90 simple and incredibly effective recipes for transforming your business data into exciting dashboards”. The authors have done a great job in selecting their recipes to cover common use cases most designers will face.  This allows readers with a specific issue to skim through the Table of Contents for a relevant recipe and then work through the provided example. The recipes cover a wide array of topics, starting with topics relevant to beginners who are looking to understand fundamental best practices, to advanced users who are looking for new creative ways to enhance their Xcelsius skills.

The first chapter provides some useful time saving tips for working with the embedded Excel spreadsheet within SAP BusinessObjects Dashboards. The later chapters of the book cover recipes for using the variety of out-of-the-box product components and present detailed coverage of topics including alerting, interactivity, and dynamic visibility. This cookbook is up to date with the SAP BusinessObjects Dashboards 4.0 release, and contains recipes for using Universe queries and directly binding query data to other canvas components.

SAP BusinessObjects Dashboards 4.0 Cookbook is a recommended resource for a wide range of users. Dashboard designers new to the product as well as more experienced users will find many useful recipes.

The book is available on the publisher’s webpage:

All you need is an egg and some imagination

6 months ago | Nirmal Merchant: Urban Gypsy

All you need is an egg and some imagination:

Julia child is so cute in this video. Got the perfect recipe for binge day..check out 24:02 in the video. Omlette with sauteed mushrooms, topped with cheese sauce, topped with cheese and then melted butter. Yummy.

Dil Tera deewana hai sanam, jaante ho tum, kuch na kahenge hum..

6 months ago | Nirmal Merchant: Urban Gypsy



Dil Tera deewana hai sanam, jaante ho tum, kuch na kahenge hum..

Jalta hai jiya mera bheegi bheegi raaton mein, aaja gori chori...

6 months ago | Nirmal Merchant: Urban Gypsy



Jalta hai jiya mera bheegi bheegi raaton mein, aaja gori chori chori abto rahan nahin jaye re, uhum hai re hai re hai re…

Bheegi bheegi raaton mein, meethi meethi baaton mein, aisi...

6 months ago | Nirmal Merchant: Urban Gypsy



Bheegi bheegi raaton mein, meethi meethi baaton mein, aisi bursaaton mein, kaisa lagta hai..

BOTS Bike Review - Trek 1.1 - an excellent all rounder

6 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

trek 1.1 review

The Trek 1.1 was reviewed by Darren Reid. We wrap up the review with our thoughts on certain technical/non-technical aspects of the bike.

About Darren

Darren Reid is a pro biker from Australia who is currently in India. He is currently sponsored by Rapha clothing (the Prada of bicycling clothing) and embrocation cycling magazine (it`s a great read. Check them out). If you like what you see, you’re welcome to ping Darren and order stuff thru him.

Darren has been racing for over 20 years and is currently helping us build and improve the Bangalore Bicycle Championships. Definitely good to have someone so experienced in our formative years!

Here’s Darren has to say about his Trek 1.1

Darren’s Thoughts

Rating the new Trek 1.1 wasn’t so hard – an excellent all rounder.

A frame designed by Trek Wisconsin, a great looking paint job, a Trek Alpha aluminum frame and fork and the thoughtful eyelets in the front and the rear for racks! The generous wheel clearance also allows for mudguards which add to the versatility of the 1.1, great for the upcoming monsoons and carrying your bag and laptop to the office!

The bike has a solid entry level Shimano groupset (Shimano 2300), Bontrager components and an FSA crank. The Trek 1.1 is not a light weight racing machine, but the 23C tires, the compact design and the racing short wheel base definitely gives you a feeling of race worthiness. It is really a bike you can use for everything – you could commute to work all week with mud guards and racks, ride it home on a friday, knock down a couple of beers and convert it into a weekend racing machine. All set to ride and train hard.

A Trek road bike under 30k. Smart buy indeed!

I have had the Trek 1.1 for a couple of days – its not as light as my other racing machines, but it did handle very very well. The ride up and down our local climb, Nandi Hills, was responsive and the bike handled very well. The compact crank allows for comfortable gear ratios to climb Nandi, especially the 34 front chainring up Nandi hill which had me spinning like Lance :-)

The Shimano 2300 never missed a gear.

I also found the aluminum frame to soak up a lot of bumps where there where bad road surfaces. I’m sure it would be a good bike for long distance Brevet rides that seem to be popular in Bangalore at the moment.

Sure I could pick things I would like to change on it, but at the end of the day it’s an excellent all rounder and great value for money given that it is a Trek and that it’s priced at under Rs. 30,000.

I would say go for it!!!

Darren’s Rating

The Trek 1.1 gets out of 5

  • Components – 3
  • Style – 4
  • Race Worthiness – 2
  • Versatility – 4.5
  • Comfort and fun – 4


BOTS Thought’s

How do we review a bike ?

At BumsOnTheSaddle we typically consider quite a few parameters before recommending a bike (We recommend only those bikes that we would buy or ride ourselves).

BOTS Parameters

  • Support/Warranty – Can the brand provide good support/warranty when there are issues (most bikers have no clue about this) Are the replacements easily available?
  • Ride – How does the bike ride ? Can it handle technical terrains or does it come with a not meant for stunts sticker on it. Is the bike spec’d and does it behave reasonably for the kind of riding intended?
  • Price – How is the bike priced when you compare it with similar models/brands in the market?
  • Brand Philosophy – We also tend to look at how the brand is positioned in the Indian market – is the brand trying to sell a container full of bikes to make a quick buck? Availability of sizing options? Availability of spares for their bikes? Do they support the local biking industry? All very important when you look at long term ownership.

Like Darren mentioned, the Trek 1.1 is a very good ride indeed and scores pretty high on most of our criteria for recommending it.

We have been using the 1.1 over the last month or so and putting it thru its paces – flats, climbs, descents, commutes, races and longish brevet rides. The bike is versatile indeed! It does lack the responsiveness and acceleration you would expect out of a really good road bike, but then you cannot expect anything better at a sub Rs 50,000 range of bikes.

The bike does not have any carbon on it – which is good considering that its not built to be a speed machine. This allows the costs to be kept down.

The bike also comes with an aluminium fork. Do read our next writeup on why this could be a boon or a bane.

The Shimano 2300 rode surprisingly well. The shifts were crisp and the bike rode exceedingly well on flats, climbs and descents. The 2300 comes with a 11-25 7 speed cassette. The front crank is a 50/32 compact crank. The gear ratios might leave you out of gears and your comfort zone if you are a beginner and hitting steep climbs like Nandi. Other than that the 2300s are great!

Who should buy this bike

  • First time road biker – you have been on crappy bikes, on MTBs etc and want to experience what open roads, road bikes and spandex is all about. Without burning a hole in your pocket!
  • Looking at getting a speed machine that you can use for most kinds of riding – weekend long rides, commute, city rides, short quick training rides
  • Training – a good second bike to have for your training rides on your trainer or outside.

If you intend to do some fast racing on this, we would recommend you save a bit more and look at bikes starting in the Rs 50,000 range. It’s worth the ride and you would spend that much or more on this bike with upgrades to get you the experience you are looking for anyways.

Upgrade path

We could make a couple of changes to make this bike ride even better – in order of priority

1. Braking – change the brake shoes to something better for a better braking experience and confidence on descents.
2. Tires – swap out the entry level Bontrager tires to racier, lighter, faster tires. Rolling can improve drastically.
3. Wheelset – the entry level wheels could be swapped out for lighter racing wheels for the peppiness you experience on more expensive racing machines. Borrow a friends wheelset and see how good the frame is.
4. Carbon – introduce carbon for better handling, reducing road buzz and comfort. You could swap in a carbon fork and a carbon seatpost.
5. Group set – if you have money left in your kitty you could upgrade to a Tiagra groupset. This would reduce weight, make your ride more efficient and give you much better control over your shifting. The additional sprocket at the rear is definitely a nice to have on your climbs.

Comparable bikes in the Indian Market

all approximate prices susceptible to change

Snaps of the Trek 1.1
<object height='300' width='400'> <param></param> <param></param> <param></param><embed src='http://www.flickr.com/apps/slideshow/show.swf?v=104087' height='300' width='400'></embed></object>

Credits
  • Darren Reid for spending precious time riding the bike, being a staunch bum at BOTS and helping us with everything bicycling in Bangalore.
  • Firefox Bikes – for giving us the Trek bike for this review. And for being super nice to the team at BumsOnTheSaddle and helping us in whatever way possible. We are not an easy bike shop to deal with :)
  • Sriharsha Maiya – (freelance photographer) For taking awesome shots of the bike.

Mixed feelings.

6 months ago | Queenie Takes Manhattan: Queenie Takes Manhattan

Nick, Louisa and I enjoyed a lovely breakfast at The Breslin last Friday. The coffee was stupendous, the baked eggs with tomato and chorizo simply glorious, and the service, frankly, lacking. At a restaurant of The Breslin's quality, I shouldn't have to wait ten minutes for sugar for my coffee.

But, man, what good coffee it is. Love you, Stumptown.

every Monday Bicycling Movie Nite's - The Atherton Project

6 months ago | Rohan Kini: blog@BumsOnTheSaddle.com - Home

The Atherton Project on Red Bull TV
The Atherton Project

Every Monday Bicycling Movie nite – we intend to watch a biking movie every monday evening. Start around 7:30pm and wrap up in about 45 mins.

Starting this Monday – 5th September
Time – 7:30pm
WhereBumsOnTheSaddle

We are watching the Season 3 of the Atherton Project this Monday

1. Why – Monday’s are boring. We want to spice up your life.
2. BYOB event – so BYOB please.
3. Everyone is welcome. Really.

Offline Google Docs - Too little too late

6 months ago | Lalatendu Das: Interpretations of Technorealism

Google (re)announced offline feature on Google docs recently. For those who noticed, would also remember that Google Gears was decommissioned nearly an year ago, hence this new HTML 5 version took too long to get to beta status. Is the new offline version worth the wait?

I guess not..here are some important notes about new offline capability (source: Google Docs help)

  • You'll need to Set up Docs offline from your Documents List to start accessing your documents and spreadsheets without an Internet connection.
  • Offline access is available in Chrome only. (Oops!)
  • Offline access is available only for documents and spreadsheets. Presentations, drawings and other items from your Documents List are not available offline at this time. 
  • (humm..okay..it's in Beta anyway)
  • Documents and spreadsheets are only available in view-only mode. You must restore your Internet connection to make any edits. (??!@#? - useless..I stopped reading next two points)
  • You can't create new documents and spreadsheets while you're offline.
  • You'll need to allow offline access separately on each computer where you want to view your Google Docs offline.

I wish Evernote comes up with a spreadsheet application. Till then, I will stick to the 'online' google docs..

Fig and Olive

6 months ago | Suman Thareja: Spice it up!..

Fancy and Pretty!  A little on the expensive side for what you get though has a few good dishes to try for sure.  With three locations around the city Fig and Olive manages to have presence in good parts of the city. The Mediterranean Chicken Samosas are addictive: Chicken, cilantro, Greek yogurt, bell pepper scallion [...]

Pastis

6 months ago | Suman Thareja: Spice it up!..

A bustling place for brunch in the meat packing district of NYC: Pastis Great brunch menu.  Make reservations before going – the wait isn’t something you would want to do.  If you like other sister restaurants like Balthazaar Resturant, Pravda, Balthazaar bakery, Lucky Strike you will like this one too. Try the Eggs à la [...]

A decade.

6 months ago | Queenie Takes Manhattan: Queenie Takes Manhattan


Ten years ago today, I moved to New York City. My first apartment was on a slightly desolate block of the Upper West Side. Today, there's a Whole Foods a block away, and four high rises have gone up within a two-block radius. Times, you could say, have changed.

I've spent my entire adult life here in Manhattan, and I wouldn't trade the experience for the world. My first few weeks were, obviously, colored by the September 11th attacks. I didn't even have my cable hooked up yet and wasn't due to start work for another week, so I spent the day curled up in my hallway listening to the radio. When I left to walk 20 blocks downtown to Caroline's apartment for company, cable and dinner, I passed Brooke Shields on the street.

That's New York, you know? The gritty reality crossed with the glamour of art and, in this case, celebrity - writ large.

My first forays into grown-up cooking were, to say the least, less than exciting. There were many grilled peanut butter and jelly sandwiches (a trick I learned from my slightly older and much wiser roommate), a lot of bottled marinara sauce, and tons of macaroni and cheese. But always a green salad. I've always been addicted to vegetables.

I spent my money at the bars and skimped on my food budget. A fancy night out was dinner at Big Nick's, an all-night pizza and burger joint on Broadway. I came home most nights by way of the local pizza place, slice in hand. I'd leave it in the oven to keep warm, hop in the shower to get rid of the bar smell (those were the days before the smoking ban, when I'd have to hang my coat on the fire escape overnight to air out the cigarette fumes), then eat the cheesy, greasy goodness while watching a movie on my hand-me-down sofa.

Today, I drink booze with flavor (bourbon or gin, not vodka), the dinners are nicer and the nights (mostly) earlier. The produce is fancier and more local, and the apartment a bit more pulled together. But the joy I feel every time I see the New York skyline, the rush I get every morning when I walk out the door, the satisfaction I take in having made it in this most insane and exciting and glorious of cities - that hasn't changed one little bit.

Thank you, New York, for raising me so well. I love you. Which is a good thing, because we seem to be stuck with one another.