Poking in ActionController

I have an ‘accept’ action in one of the controllers and when I was trying to run a functional test against it I got:

ActionController::UnknownAction in 'ContributorRequestsController for moderator allow to accept a request'
No action responded to accept

And of course it worked fine when I’ve actually started the server and invoked it from browser.

I’ve realized that the reason probably was some name clashing or something, but it only appeared in the tests. So I’ve decided to have some debugging fun and I think the outcome is the case when code extracts speak louder than words:

ActionController::Base:

def perform_action
  if self.class.action_methods.include?(action_name) 
    ...
  else
    raise UnknownAction, "No action responded to #{action_name}", caller
  end
end

def self.action_methods
  @action_methods ||= Set.new(public_instance_methods - hidden_actions)
end

def hidden_actions
  write_inheritable_attribute(:hidden_actions, ActionController::Base.public_instance_methods) unless read_inheritable_attribute(:hidden_actions)
  read_inheritable_attribute(:hidden_actions)
end

If your action is named as one of the ActionController::Base.public_instance_methods then it won’t be invoked. While that’s reasonable, I wondered what that reserved ‘accept’ method did. I’ve failed to find it in the rails and rspec sources and finally simply did a search for ‘def accept’ against the project and found it in lib/authenticated_test_helper.rb which is generated by acts_as_authenticated plugin.

def accept(accept)
  @request.env["HTTP_ACCEPT"] = accept
end