abstract_controller.rb

Path: lib/merb-core/controller/abstract_controller.rb
Last Update: Mon Mar 08 20:24:42 -0700 2010

Why do we use Underscores?

In Merb, views are actually methods on controllers. This provides not-insignificant speed benefits, as well as preventing us from needing to copy over instance variables, which we think is proof that everything belongs in one class to begin with.

Unfortunately, this means that view helpers need to be included into the <strong>Controller</strong> class. To avoid causing confusion when your helpers potentially conflict with our instance methods, we use an _ to disambiguate. As long as you don‘t begin your helper methods with _, you only need to worry about conflicts with Merb methods that are part of the public API.

Filters

before is a class method that allows you to specify before filters in your controllers. Filters can either be a symbol or string that corresponds to a method name to call, or a proc object. if it is a method name that method will be called and if it is a proc it will be called with an argument of self where self is the current controller object. When you use a proc as a filter it needs to take one parameter.

after is identical, but the filters are run after the action is invoked.

Examples
  before :some_filter
  before :authenticate, :exclude => [:login, :signup]
  before :has_role, :with => ["Admin"], :exclude => [:index, :show]
  before Proc.new { some_method }, :only => :foo
  before :authorize, :unless => :logged_in?

You can use either :only => :actionname or :exclude => [:this, :that] but not both at once. :only will only run before the listed actions and :exclude will run for every action that is not listed.

Merb‘s before filter chain is very flexible. To halt the filter chain you use throw :halt. If throw is called with only one argument of :halt the return value of the method filters_halted will be what is rendered to the view. You can override filters_halted in your own controllers to control what it outputs. But the throw construct is much more powerful than just that.

throw :halt can also take a second argument. Here is what that second argument can be and the behavior each type can have:

  • String: when the second argument is a string then that string will be what is rendered to the browser. Since merb‘s render method returns a string you can render a template or just use a plain string:
      throw :halt, "You don't have permissions to do that!"
      throw :halt, render(:action => :access_denied)
    
  • Symbol: If the second arg is a symbol, then the method named after that symbol will be called
      throw :halt, :must_click_disclaimer
    
  • Proc: If the second arg is a Proc, it will be called and its return value will be what is rendered to the browser:
      throw :halt, proc { access_denied }
      throw :halt, proc { Tidy.new(c.index) }
    
Filter Options (.before, .after, .add_filter, .if, .unless)
:only<Symbol, Array[Symbol]>:A list of actions that this filter should apply to
:exclude<Symbol, Array[Symbol]:A list of actions that this filter should not apply to
:if<Symbol, Proc>:Only apply the filter if the method named after the symbol or calling the proc evaluates to true
:unless<Symbol, Proc>:Only apply the filter if the method named after the symbol or calling the proc evaluates to false
:with<Array[Object]>:Arguments to be passed to the filter. Since we are talking method/proc calls, filter method or Proc should to have the same arity as number of elements in Array you pass to this option.
Types (shortcuts for use in this file)
Filter:<Array[Symbol, (Symbol, String, Proc)]>

params[:action] and params[:controller] deprecated

params[:action] and params[:controller] have been deprecated as of the 0.9.0 release. They are no longer set during dispatch, and have been replaced by action_name and controller_name respectively.

[Validate]