Feb 242010

I discovered an interesting difference between two patch levels of the same Ruby (1.8.7)

def index
 respond_to do |format|
  format.html {
   super # call the index method of the superclass

This does not produce an error in Ruby 1.8.7 patchlevel 72 (the one that happens to ship with Snow Leopard), but in Ruby patchlevel 249 (the most recent one), it tells me I’m not allowed to do this.

super called outside of method

If you think about it from an OOP perspective it actually makes a lot of sense that this would be illegal programming – super is being called from within a block that is passed to respond_to. So, although the intended meaning appears clear from the way the code is written, the Ruby devs probably saw this as something that should be prohibited and fixed Ruby to make it so. Hence, apps written by programmers unaware of this using earlier patch levels may see this after upgrading to the latest Ruby 1.8.7

 Posted by at 8:20 pm  Tagged with:
Feb 182010

This method was adapted from this blog post.

So, you are creating a thing (record) or maybe you are updating it. You’ve added created_by and updated_by fields to your model, and you’ve made these integers with the intention of them both being foreign keys to the Users model.

Maybe you’ve even setup a belongs_to relationsion to your User model like so:

class Thing
 belongs_to :creator, :foreign_key => ‘created_by’, :class_name => ‘User’
 belongs_to :updater, :foreign_key => ‘updated_by’, :class_name => ‘User’

(this way you can refer to thing.creator and thing.updater)

Now, you want to actually set these fields when you create a record or update a record. Problem is, your current_user method is a controller method, and isn’t available in your model layer.

Well, this IS a problem. There are many ways to hack it- but here’s the best approach. I’m going to do this backwards for clarity.

1. Make user_info.rb in your models directory

module UserInfo
 def current_user

 def self.current_user=(user)
  Thread.current[:user] = user

2. Now you need the TrackUsers class, which is real simple. Make another file in your models class called “track_users.rb”. Notice that we’re mixing in the UserInfo module we just created.

module TrackUsers
 # mix me into the OBSERVER for any class you want to set the created_by, updated_by fields
 include UserInfo
 def before_update(record)
  record.updated_by = current_user.id if current_user
 def before_create(record)
  record.created_by = current_user.id if current_user

3. Make an observer class for Thing (you can make this in your models folder). Call the file “thing_observer.rb”. Notice that all this basically does is mix in the TrackUsers module.

class ThingObserver < ActiveRecord::Observer
 include TrackUsers

4. Setup an Observer for your (this goes inside the Rails::Initializer.run do |config| block)

 config.active_record.observers = [

5. In your ApplicationController add this:

 before_filter :set_user

 # … some more of your code …

 def set_user
  if current_user
   UserInfo.current_user = current_user

 Posted by at 11:30 am  Tagged with:
Feb 162010

The referrer is the URL the user came from. (It gets passed as part of the headers to the new request). You can get it out of rails this way:


Or the shorter version:


It seems that no one noticed that “referer” is actually not a word – the correct spelling is double-R (“referrer”). request.referer and request.referrer both work, but request.env[‘HTTP_REFERRER’] does not.

 Posted by at 3:49 pm  Tagged with: