annealer annealer

gabriel gironda will have his revenge on seattle

Interesting Rails commits, Volume #1

Written on Monday, December 29, 2008

Here’s a rundown of recent Rails commits I’ve found of interest. I’ll probably be continuing this series of posts until either people stop committing to Rails or I get bored of doing it, which ever one comes first. No fixed schedule, just when I think there’s enough interesting commits to post about.

Multiple condition support in ActiveSupport::Callbacks

As of commit 1e45818a622405e720a4529795f8be2f11660361, ActiveSupport::Callbacks now supports multiple conditions. What this means is you can now write code like this:

    
    class Hero < ActiveRecord::Base
      before_save :add_awesome_robert_fripp_feedback, :if => [:bowie_original, Proc.new {|s|s.not_a_shitty_cover?}]
      before_save :tony_viscontiize, :unless => [:not_a_bowie_original, Proc.new {|s|!s.not_a_shitty_cover?}]
    end
    

In this case, the first callback will only run if both the method bowie_original and the Proc that checks for not_a_shitty_cover return true. The second callback will run unless any of the specified conditions return true - that is, tony_viscontiize will get called unless not_a_bowie_original is true or the given Proc returns true. Both must be false for it to be called.

Remember, these are in ActiveSupport::Callbacks, so you can make use of this functionality in your own code that uses the module, ActiveRecord, or anywhere else in Rails using it.

Dynamic scopes in ActiveRecord

Commit 66ee5890c5f21995b7fe0c486547f1287afe2b55 adds dynamic scopes to ActiveRecord. Much like the dynamic finders, you can now create dynamic scopes.

    
    # This new call:
    User.scoped_by_user_name('joe').all 
    
    # Is equivalent to this named scope:
    class User
      named_scope :user_name, lambda { |name| 
        {:conditions => ["user_name = ?", name]} 
      }
    end
    

If you haven’t yet checked out named scope, take a look at it. It’s useful for moving a lot of code back into the class it belongs in, outside of things like AssociationProxy extensions.

HTTP Digest authentication

Finally, commit 45dee3842d68359a189fe7c0729359bd5a905ea4 adds HTTP Digest authentication support to ActionController, alongside the existing support for HTTP Basic authentication. A common usage case could look like:

  
    class TrackController < ApplicationController
      before_filter :authenticate
      
      def index
        render
      end
      
    private
    
      def authenticate
        # This block must return the expected password
        authenticate_or_request_with_http_digest("Secure Area") do |user_name|  
          User.find_by_username(user_name).password
        end
      end
      
    end
    

A change from Basic authentication is that you must be able to get at the expected password and return it as the result of the block. So if you’re salting and hashing passwords in the database, there’s a great chance Digest authentication isn’t going to work for you. If you’re encrypting them instead and are already using Basic authentication, consider looking at Digest authentication for a slightly more secure mechanism of checking credentials.

blog comments powered by Disqus

Annealer, a Jekyll powered blog by Gabriel Gironda.