Tatva-Artha

meaning of "it"

Archive for November, 2009

Upgrading Ubuntu: from 9.04 to 9.10

without comments

So, after ignoring the new upgrade in my update-manager for several months, I finally decided to upgrade today.

I don’t remember any major headaches when upgrading from v8.10 to 9.04 except for a few config files (mysql’s my.cnf) being changed. However, this time it wasn’t as smooth.

The total time it took to download and install upgrade was around 2.5-3 hours. On the upside, it did upgrade my netbeans version automatically from 6.5 to 6.7, which I meant to do one of these days. However, the default version of Netbeans didn’t have ruby plugin in it. So, I had to patch that manually and install other plugins that aren’t default in netbeans (e.g. haml).

Mysql upgrade wasn’t as smooth. The server didn’t install properly and won’t start. It was time to roll up sleeves and get to work (should’ve planned timing properly!)

# try starting daemon
$ sudo /etc/init.d/mysql start
# won't start, time to tail daemon log
$ tail -f /var/log/daemon.log
# found that /var/run/mysqld folder is missing

After some googling, found that this is an issue with v9.10 upgrade. References here and here. The workarounds mentioned in these bug-reports didn’t work for me. I had to uninstall and install mysql-server.

$ sudo apt-get remove mysql-server
$ sudo apt-get install mysql-server
# try restarting server
$ sudo /etc/init.d/mysql start

Lucky me, re-installing mysql-server doesn’t delete any existing databases and those database files work with new version of mysql-server.

Lesson Learnt: Upgrade only when you have 4-6 hours of spare time in hand.

Initial impression about the upgrade is mixed. I am happy that I am “current”, however not sure what else it out there broken waiting to eat a few more hours. Also, I do miss the old color theme over new one. I should get used to new theme with time though.

Written by Sharad

November 27th, 2009 at 10:04 am

Posted in All

Manipulating image using RMagick

without comments

An example of manipulating image using RMagick

require 'RMagick'
image = Magick::Image.read("original.jpeg").first
image.change_geometry("100x100") do |c,r,i|
  i.resize!(c,r)
  i.write 'out.jpeg'
end

Written by Sharad

November 14th, 2009 at 5:41 am

Posted in All

Installing rmagick on Ubuntu 9.04 – Jaunty Jackalope

without comments

Most help that turn up on google with installing rmagick on linux/ubuntu suggest installing following packages:

$ sudo apt-get install ruby rubygems irb ri rdoc ruby1.8-dev build-essential imagemagick libmagick9 libmagick9-dev
$

On my Ubuntu 9.04, it couldn’t find libmagick9-dev. I got following error:

$ sudo apt-get install libmagick9-dev
[sudo] password for sjain: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package libmagick9-dev is a virtual package provided by:
  libmagickwand-dev 7:6.4.5.4.dfsg1-1ubuntu3.1
You should explicitly select one to install.
E: Package libmagick9-dev has no installation candidate
$

Installing ‘libmagickwand-dev did the trick:

sudo apt-get install libmagickwand-dev

Then the following worked:

$ sudo gem install rmagick
Building native extensions.  This could take a while...
Successfully installed rmagick-2.12.2
1 gem installed
$

Written by Sharad

November 14th, 2009 at 5:16 am

Posted in All

Ruby Authlogic: lazy initialization based on defined?() call

without comments

What is the difference between following two versions of code?

  # Version: V1
  def current_user_session
    return @current_user_session if defined?(@current_user_session)
    @current_user_session = UserSession.find
  end

This is very similar to following code:

  # Version: V1
  def current_user_session
    unless @current_user_session
      @current_user_session = UserSession.find
    end
    @current_user_session
    # the above code could also be written as: @current_user_session ||= UserSession.find
  end

The difference is that V1 optimizes the code is by making that expense “UserSession.find” query only once per lifetime of enclosing class (which, if you’ve used authlogic, you recognize that it is the ApplicationController class). Then V2 version is a bit inefficient in that if the UserSession.find happens to be nil (when the user is not logged in), it continues to call UserSession.find each time this method is called. Fair enough.

However, this messes up your test if you aren’t writing your test with this fact (the first call to current_user_session method will fix the value of @current_user_session and cannot be changed for the entire test run) in mind.

Consider this test, which passes:

  # Test for when "logout" is invoked, the user-session is properly destroyed and user is redirected
  context "with a logged-in user" do
    setup do
      User.create(:username => "foo", :email => 'foo@company.com', :password => "secret", :password => "secret")
      UserSession.create(:username => "foo", :password => "secret")
      assert controller.logged_in?
    end
    should "destroy session and redirect to root page on logout" do
      post :destroy
      assert_nil(UserSession.find)
      assert_redirected_to root_url
    end
  end

Now, if you introduce a print statement to print the current_user_session after the user is logged in, it will mess up the test and your test will fail:

  # Test for when "logout" is invoked, the user-session is properly destroyed and user is redirected
  context "with a logged-in user" do
    setup do
      User.create(:username => "foo", :email => 'foo@company.com', :password => "secret", :password => "secret")
      # The following line is to make sure user is not logged in initially
      # However, this line will end up calling controller.current_user_session and will fixate @current_user_session to nil for the rest of the test !!!
      assert_nil controller.logged_in?
      UserSession.create(:username => "foo", :password => "secret")
      assert controller.logged_in?
    end
    should "destroy session and redirect to root page on logout" do
      post :destroy
      assert_nil(UserSession.find)
      assert_redirected_to root_url
    end
  end

I can see the reasoning for V1 but I still prefer V2, even though it is little ‘inefficient’.

Written by Sharad

November 12th, 2009 at 10:31 pm

Posted in All

Ruby ActiveRecord: How to implement has_few using has_one and belongs_to

without comments

Google search for has_one vs. belongs_to reveals that the concept is a little confusing and it takes some practice for it to settle in. From Ruby Doc, it appears that in a one-to-one cardinality, we are free to choose which class holds “has_one” and which holds “belongs_to”, with belongs_to class’s database table schema holding the foreign key relationship.

Depending on your business case, one object comprises of other and hence the comprising object ends up having “has_one” side of it. For example, a mortgage application has a borrower_profile. And hence, one can say that borrower_profile belongs to a mortgage application. This is modelled as:

class MortgageApplication
  has_one :borrower_profile
end
class BorrowerProfile
  belongs_to :mortgage_application
end

So far, it’s good.

However, what happens when a mortgage application allows a co-borrower profile? Now we have one-to-TWO relationship that we need to model. One way to model this would be to think of it as one-to-many relationship and add custom validation to ensure that there are a maximum of 2 borrowers for a given mortgage application.

class MortgageApplication
  has_many :borrower_profiles, :order => "borrower_order ASC"
end
class BorrowerProfile
  belongs_to :mortgage_application
end

The :o rder option is needed to ensure that first item in list is the borrower and second item is the co-borrower.

That could work. But, strictly speaking a mortgage application has-one borrower and has-one co-borrower. So, can we model it using has-one/belongs-to? Let’s try.

class MortgageApplication
  has_one :borrower_profile # default: table = borrower_profiles, foreign_key = mortgage_application_id
  has_one :coborrower_profile, :class_name => "BorrowerProfile", :foreign_key => :mortgage_application_id
end
class BorrowerProfile
  belongs_to :mortgage_application
end

The above code won’t work since both borrower_profile and coborrower_profile are being looked up using same foreign key. The problem here is that MortgageApplication needs to foreign key to refer to each of the borrowers. The problem can be resolved by keeping the foreign keys in the mortgage_applications table instead of borrower_profiles table, effectively flipping the has-one/belongs-to relationship. Here we go:

class MortgageApplication
  belongs_to :borrower_profile # default: table = "BorrowerProfile", foreign_key = "borrower_profile_id"
  belongs_to :coborrower_profile, :class_name => "BorrowerProfile", :foreign_key => "coborrower_profile_id"
end
class BorrowerProfile
  has_one :mortgage_application
end
 
# Problem: coborrower.mortgage_application will always be null

The above will solve the problem with mortgage_application pointers to borrower_profile. However, bi-directional relationship from borrower to mortgage-application will only work for primary borrower and not for co-borrower. This is because the lookup for mortgage-application from borrower model will always be attempted using foreign-key: borrower_profile_id.

So, we do the following:

class MortgageApplication
  belongs_to :borrower_profile # default: table = "BorrowerProfile", foreign_key = "borrower_profile_id"
  belongs_to :coborrower_profile, :class_name => "BorrowerProfile", :foreign_key => "coborrower_profile_id"
end
class BorrowerProfile
  has_one :mortgage_application
  # coborrower will use following reference to mortgage-application
  has_one :comortgage_application, :class_name => "MortgageApplication", :foreign_key => "coborrower_profile_id"
end

The above code solves that problem of reverse reference from borrower-profile to mortgage-application for both borrower as well as co-borrower. The only wrinkle is that when looking up mortgage application for co-borrower, we have to use comortgage_application reference. This wrinkle could be wrapped inside the object by overriding “mortgage_application” method.

As we can see, it is possible to map has-few relationship using either has_many/belongs_to or has_one/belongs_to. Each approach has some wrinkles and we can use either depending on which fits our style of programming.

Written by Sharad

November 8th, 2009 at 11:16 pm

Posted in All