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.

blog comments powered by Disqus