04 March 2010

Using ActiveSupport::Dependencies outside a Rails project

I wanted to have the ability to auto-load dependencies based on the symbol name the way Rails does in my own non-Rails project, as it would save me writing a lot of require statements.

This can be achieved using ActiveSupport.

I added a file called boot.rb which is included in the other files of the project.

First of all, the file should require the active_support gem. I use Bundler, so in my case I specified a dependency on activesupport in Gemfile and then loaded the Bundler environment in boot.rb:

require "#{File.dirname(__FILE__)}/vendor/bundler_gems/environment"
Bundler.require_env  

After that, I added the following lines:

include ActiveSupport
Dependencies.load_paths << File.join(File.dirname(__FILE__), 'config')
Dependencies.load_paths << File.join(File.dirname(__FILE__), 'lib')
This code means that unknown symbols will be resolved by searching the files inside the config and lib folders. Also, to force the inclusion of a particular file in case the load can't be triggered by an unknown symbol name, you can do:
Dependencies.depend_on("activerecord_extensions") 
After setting up boot.rb, you just need to require it in the files that do actual real work to get automatic dependency loading:
require File.expand_path("#{File.dirname(__FILE__)}/boot")

Works using: activesupport 2.3.5

Create long integer or double precision columns

Rails doesn't provide types to create long integer or double precision columns, however it can be done using the :limit parameter:

create_table :my_table do |t|
  t.integer :long_int_column, :limit => 8
  t.float :double_column, :limit => 53
end

8 and 53 are magic numbers. I normally generate the migration first and then modify the migration file to add the limit parameter.

This works for PostgreSQL and MySQL databases, but I haven't tried any others.

Works on: Rails 2.3.5

Delete expired ActiveRecord based sessions regularly

Rails doesn't do anything about expired sessions by default. Here is how I take care of that in the case of ActiveRecord based sessions.

I have a file called delete_expired_sessions.rb in my_app/lib folder containing the call to delete old sessions:

ActiveRecord::SessionStore::Session.delete_all(["updated_at < ?", 12.hours.ago])
I also have an entry in the crontab which executes this script at 4am every day:
0 4 * * * cd /data/my_app/current && RAILS_ENV=production ./script/runner lib/delete_expired_sessions.rb

The only other thing is to make sure that you regularly write something into active sessions so they don't go stale and get deleted. And that's it.

Works on: Rails 2.3.5