Rails best practices Part 1

April 26, 2006

Best Practices: Sessions

I've been writing rails apps for a few months now. The most painful lesson I've learned is to be careful how you use sessions…. If you don't handle your sessions properly you will become a very frustrated developer. Trust me 🙂

Here are a few best practices I've observed with regards to sessions:
1) keep them small. Sessions get reloaded from database (or file) for every single hit on the application. Don't put hundreds of objects in a session or you're going to slow things way down. Rethink your design if you start seeing a need to have more than a few objects in a session.

2) put only "primitive" types in sessions. I know Ruby doesn't have primitive types, but you know what I mean – Integers, Strings, Floats. So instead of putting a "User" model in the session, put the "user id" in the session and when you need the model do this instead: user = User.find(session[:user_id]). If you do this you won't have to worry about having serialization/deserialization issues every time you roll out new code. If you put models in your sessions, you not only have the overhead of the database hit to reload these models for every hit, but you have to deserialize the models to instantiate them. If the object schema of the model changes the application won't (probably) be able to re-instantiate these models and your user will be left with an error message. If you need to store models in the session for some reason, make sure you wipe all your sessions as part of your deployment process.

3) For development have a script to delete your sessions (I use file sessions for dev). When your dev environment starts acting strangely, just run the script and clean them up. It may not solve your problem, but at least it eliminates session funkiness as the cause. This is much more important if you put models in your sessiosns.

4) Schedule a batch process to expire your sessions. You want to "expire" sessions at some point (there will be a performance hit if the sessions table gets to big). Here's our rake task for cleaning the sessions table:

desc "Delete row from the session table that have not been updated in ENV['DAYS_OLD'] days, default is 1.
Set RAILS_ENV on command line to hit correct database."
task :clean_session_table => :environment do

days_ago = ENV['DAYS_OLD'] || 1
remove_if_older_than = Date.today – days_ago.to_i

old_sessions = CGI::Session::ActiveRecordStore::Session.find(:all, :conditions => ['updated_at <= ?', remove_if_older_than], :order => 'updated_at' )
puts "Removing #{old_sessions.length } sessions that are older than #{remove_if_older_than} from the #{ENV['RAILS_ENV']} database" unless ENV['SILENT']

puts "Destroying old session from #{old_session.updated_at} #{old_session.destroy ? '– Sucess' : '– Failure'}" unless ENV['SILENT']

That's it for today…



In the beginning…

March 8, 2006

Collective Intellect is a Web2.0 sort of company that I co-founded in the spring of 2005 to address the information blind spot in the trading community brought about by this very medium. Blogs have been shown to lead traditional media by days and sometimes weeks and in the investment business this is a very big deal. The problem is the noisiness of the channel. It’s hard to discover what could be important in a sea of self promotion, grievances, personal stories about your latest trip, and so on. We’ve been successful at creating text analysis algorithms to automate this daunting task. One of the reasons for our success has been the choice of Ruby and Ruby on Rails.

Very early in the company I decided to take a step back from the land of Java, and application servers, Struts, JMS, JavaMail, EJB, Spring, Mule, Ant, Xerces, Hibernate, JDOM, … I was reading Paul Graham’s book, “Hackers and Painters” and it got me thinking about whether there might be a language that would allow me to get more done with less code, in a more elegant way. My background had been C, C++, and then Java. We had done a bit of work in python and lisp seemed to be too far outside the object paradigm. So, based on one of the chapters in Paul’s book I started playing around with Ruby.

The expressiveness of the language with its conditional assignments, collection operators, ? boolean and ! change self methods are great. The code is smaller, easier to read, and gets more done. The yield took some getting used to but once even semi-mastered offered infinitely more flexibility than the languages I was used to working in. The ability to modify classes or methods on the fly turns out to be more useful than you would at first expect. And the fact that the Ruby runtime executes the commands as it is parsing through the file allows you to modify the language to some degree to better suit the problem domain (rails is an excellent example of this, and is often referred to as meta-programming).

We’re currently using Ruby to crunch through most of our back-end processing requirements and have adopted the persistence framework in RoR (ActiveRecord) to perform the OO mapping. BTW, ActiveRecord is one of the cleanest, easiest to use ORM layers I’ve ever used! We started out using Flex for our front-end development but have switched entirely over to RoR, AJAX, et al.  We’ve taken a small very good team of expert Java developers and in short order they’ve transformed themselves into quite happy, ass kicking Ruby/Rails developers.  (Also, thanks to Dave Thomas and the pragmatic guys who put on the Rails Studios).
We’re planning to use this forum to publish experiences with Ruby/Rails, list ideas, get feedback, and take resumes 😉

Thanks Matz. Thanks DHH and to all who’ve contributed to Ruby and RoR. We couldn’t have done it this fast without you.



Tim Wolters, CTO, Collective Intellect