Archive for November, 2009
Upgrading Ubuntu: from 9.04 to 9.10
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.
Manipulating image using RMagick
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
Installing rmagick on Ubuntu 9.04 – Jaunty Jackalope
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 $
Ruby Authlogic: lazy initialization based on defined?() call
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’.
Ruby ActiveRecord: How to implement has_few using has_one and belongs_to
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
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.