Using Metal with live-validations
The popular live-validations plugin for Rails works by providing a controller that is polled asynchronously by Ajax-requests. I decided that re-implementing this controller as a piece of Metal (a way to write super fast pieces of optimized logic that routes around Action Controller in Rails 2.3+) would be a nice learning-opportunity. I started out by watching Gregg Pollack's screencast on Rack, Metal, and Rails Middleware – highly recommendable if you want to learn more about any of the mentioned technologies. After watching I was able to whip up some code:
# Allow the metal piece to run in isolation require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails) # Drop-in replacement for the LiveValidations controller that ships with # live-validations. class ValidationPoller def self.call(env) if env["PATH_INFO"] =~ /^\/live_validations\/uniqueness/ params = HashWithIndifferentAccess.new(Rack::Request.new(env).params) responder = LiveValidations.current_adapter.validation_responses[:uniqueness] [200, {"Content-Type" => "text/html"}, [responder.respond(params).to_s]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end end end
As described in the comments, this really is a drop-in solution (just store the
file in the app/metal folder). The controller
that ships with live-validations will never be reached (or any other part of
Rails – this all happens before the Rails routing process is triggered). We use
this in production for crantastic (my GSoC 2009 project) without any
problems. If you have a really big site this will probably give you a small
improvement in performance – I haven't done any benchmarking though.