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.
annealer