In Rails controllers, the usual way to write a method which uses parameters given in the request URL is like this:


class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
  end
end

The new MVC framework for .NET from Microsoft allows the developer to write more natural-looking methods, giving them parameters and having the framework set their values from the query string. This made me wonder: why can't Rails do this?

I patched my copy of actionpack/lib/action_controller/base.rb to make this work. I added a require for 'parse_tree', edited perform_action so that instead of send(action_name), it calls invoke_action_method, and implemented invoke_action_method like this:


def invoke_action_method

  param_names = ParseTree.translate(self.class, action_name)[2][1][1][1..-1]
  
  real_params = params.reject { |k, v| ['controller', 'action'].include?(k) }

  if param_names.length == method(action_name).arity
    send(action_name, *(param_names.collect { |name| real_params[name] }))
  else
    send(action_name)
  end

end

Now my controller methods look like this:


class PostsController < ApplicationController
  def show(id)
    @post = Post.find(id)
  end
end

This is probably slow and fragile. I'd like to hear ideas for improving it.

No comments