Skip to main content

Mobomo webinars-now on demand! | learn more.

I love the new constraints feature of Rails 3 routing. It opens up powerful new avenues for handling certain scenarios before a request is even delivered to the controller. One thing that bugs me, though, is that making a new class for any non-standard request-based constraint is kind of a pain. Rather than this:

class SignedInConstraint   def self.matches?(request)     !request.session[:user_id].blank?   end end  root :to => 'controller#index', :constraints => SignedInConstraint 

I'd much rather be able to simply write:

root :to => 'controller#index', :constraints => lambda{|req| !req.session[:user_id].blank?} 

So I mentioned wanting to patch Rails to make this work in Presently and got a brilliantly pragmatic response from fellow Intridean Jeremy McAnally:

Update: As Jose Valim pointed out, this is actually built in to the Rails 3 source. While I wasn't aware of this feature, after calling matches? it will check for call. So you can do this with no core class modification...it just works!

scope :constraints => lambda{|req| !req.session[:user_id].blank? } do   # all my logged in routes end 

This post started out as a simple core class hack to enable some new functionality in Rails. Now it's been transformed into an announcement: Rails 3 supports lambda routing constraints by default! Bonus points to the Rails core team for thinking this through well before I tried to hack it.

Categories
Author
1
Subscribe to Constraints