File: abstract_controller.rb

# abstract_controller.rb

Path: | lib/merb-core/controller/abstract_controller.rb
Last Update: | Tue Mar 03 13:34:13 -0700 2009

#### 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]