Brian Corrales
corralesonline.com

RAILS 2.0 Sessions

February 13th, 2008 . by brian.corrales

So I just updated a project to RAILS 2.0. There’s been a few stumbles on the way, but the main issue I came across was Sessions. It seems that the RAILS team has decided to move away from file-system sessions to cookie sessions. Cookies seem to be much faster than the old file system. The only draw back is that it forces you to utilize session variables as intended…sparingly. Cookies are generally limited to only 4K. There really isn’t any need for you to ever store more than this in your session anyway. It’s just not considered best-practices.

So if you are upgrading to Rails 2.0 and you get some errors, such as a 500 Error, be sure to check how you are handling sessions. Regardless, you’ll need to add the following code into your environments.rb file (don’t forget to restart your server):

config.action_controller.session = { 
  :session_key => _my_app_session, 
  :secret      => hashed_key_of_at_least_30_characters 
}

If you want to read the documentation, here’s the link: http://caboo.se/doc/classes/CGI/Session/CookieStore.html .

For a really good discussion on Sessions and RAILS, go here.


Ordering Eager-loaded Data

February 1st, 2008 . by brian.corrales

If you are using Active Record with Ruby on Rails, I’m sure you’re familiar with the :include symbol for the find method. Here’s an example where we have a category structure of Categories -> SubCategories:

@category = Category.find(params[:id], :include => [:sub_categories])

This will find the category with id = params[:id] and will eager load all of the related sub categories. This way we only need to run one query, rather than two. We could also do this

@category = Category.find(params[:id], :include => [:sub_categories, {:sub_categories => :products }])

Now we are going down another level and retrieving all products related to each sub_category. Unfortunately, there is no way to go travel further into your data model with the :includes symbol. If anyone has a good approach, I’m all ears.

The problem I’ve run into is that my Category model has has_many :sub_categories, :order => ‘rank asc’. When I include :sub_categories, Active Record does not recognize my ordering. This caused me quite a few headaches until I came across this in the docs:

” Since the eager loading pulls from multiple tables, you‘ll have to disambiguate any column references in both conditions and orders. So :order => “posts.id DESC” will work while :order => “id DESC” will not. Because eager loading generates the SELECT statement too, the :select option is ignored.” Here’s the link:

So the best approach would be @category = Category.find(params[:id], :include => [:sub_categories, {:sub_categories => :products}], :order => “categories.rank, sub_categories.rank”)

This will order your categories and sub categories. Hopefully someone finds this useful. If you have come up with a better approach, please let me know.