Tatva-Artha

meaning of "it"

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’.

http://www.tatvartha.com/wp-content/plugins/sociofluid/images/digg_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/reddit_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/stumbleupon_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/delicious_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/google_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/twitter_16.png

Related posts:

  1. Working with Authlogic in script/console When probing / debugging issues with Authlogic on rails console,...
  2. Authlogic: after the initial hype On my rails projects, I’ve used restful_authentication before and I...
  3. Getting session_id in rails If you are using database sessions, rails sessions table stores...
  4. Environment specific routing in rails For better application support, it is usually nice to build...
  5. Login as multiple users simultaneously for testing Ever wondered how to login as two different users...

Related posts brought to you by Yet Another Related Posts Plugin.

Written by Sharad

November 12th, 2009 at 10:31 pm

Posted in All

Leave a Reply