Class: Merb::AbstractController

Attributes

NameRead/write?
_benchmarks RW
thrown_content RW

Public Class Methods


add_path_to_template_cache (template)

Adds a path to the template path cache. This is requried for any view templates or layouts to be found during renering.

Example

Merb::AbstractController.add_path_to_template_cache(’/full/path/to/template.html.erb’)

    # File lib/merb/abstract_controller.rb, line 67
67:     def self.add_path_to_template_cache(template)
68:       arry = template.split("/").last.split(".")
69:       return false if template == "" || arry.size != 3
70:       key = template.split(".")[0..-2].join(".")
71:       self._template_path_cache[key] = template
72:     end

inherited (klass)

    # File lib/merb/abstract_controller.rb, line 18
18:       def inherited(klass)
19:         _abstract_subclasses << klass.to_s unless _abstract_subclasses.include?(klass.to_s)
20:         super
21:       end

new (*args)

    # File lib/merb/abstract_controller.rb, line 28
28:     def initialize(*args)
29:       @_benchmarks = {}
30:       @thrown_content = AbstractController.default_thrown_content
31:     end

reset_template_path_cache! ()

Resets the template_path_cache to an empty hash

    # File lib/merb/abstract_controller.rb, line 75
75:     def self.reset_template_path_cache!
76:       self._template_path_cache = {}
77:     end

Protected Class Methods


after (filter, opts={})

after is a class method that allows you to specify after filters in your controllers. Filters can either be a symbol or string that corresponds to a method name 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. When you use a proc as a filter it needs to take one parameter. You can gain access to the response body like so: after Proc.new {|c| Tidy.new(c.body) }, :only => :index

     # File lib/merb/abstract_controller.rb, line 199
199:     def self.after(filter, opts={})
200:       add_filter((self.after_filters ||= []), filter, opts)
201:     end

before (filter, opts={})

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.

examples:

  before :some_filter
  before :authenticate, :exclude => [:login, :signup]
  before Proc.new {|c| c.some_method }, :only => :foo

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 of the method filters_halted will be what is rendered to the view. You can overide filters_halted in your own controllers to control what it outputs. But the throw construct is much more powerful then just that. throw :halt can also take a second argument. Here is what that second arg can be and the behavior each type can have:

  • String: when the second arg 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.new {|c| c.access_denied }
      throw :halt, Proc.new {|c| Tidy.new(c.index) }
    
     # File lib/merb/abstract_controller.rb, line 187
187:     def self.before(filter, opts={})
188:       add_filter((self.before_filters ||= []), filter, opts)
189:     end

default_thrown_content ()

     # File lib/merb/abstract_controller.rb, line 224
224:     def self.default_thrown_content
225:       Hash.new{ |hash, key| hash[key] = "" }
226:     end

skip_after (filter)

Exactly like skip_before, but for after filters

     # File lib/merb/abstract_controller.rb, line 220
220:     def self.skip_after(filter)
221:       skip_filter((self.after_filters || []), filter)
222:     end

skip_before (filter)

Call skip_before to remove an already declared (before) filter from your controller.

Example:

  class Application < Merb::Controller
    before :require_login
  end

  class Login < Merb::Controller
    skip_before :require_login  # Users shouldn't have to be logged in to log in
  end
     # File lib/merb/abstract_controller.rb, line 214
214:     def self.skip_before(filter)
215:       skip_filter((self.before_filters || []), filter)
216:     end

Public Instance Methods


dispatch (action=:to_s)

    # File lib/merb/abstract_controller.rb, line 33
33:     def dispatch(action=:to_s)
34:       caught = catch(:halt) do
35:         start = Time.now
36:         result = call_filters(before_filters)
37:         @_benchmarks[:before_filters_time] = Time.now - start if before_filters
38:         result
39:       end
40:     
41:       @_body = case caught
42:       when :filter_chain_completed
43:         call_action(action)
44:       when String
45:         caught
46:       when nil
47:         filters_halted
48:       when Symbol
49:         send(caught)
50:       when Proc
51:         caught.call(self)  
52:       else
53:         raise MerbControllerError, "The before filter chain is broken dude. wtf?"
54:       end
55:       start = Time.now
56:       call_filters(after_filters) 
57:       @_benchmarks[:after_filters_time] = Time.now - start if after_filters
58:     end

Protected Instance Methods


call_action (action)

    # File lib/merb/abstract_controller.rb, line 81
81:     def call_action(action)
82:       # [[:id], [:foo, 7]]
83:       args = self.class.action_argument_list[action.to_sym].map do |arg_default|
84:         arg = arg_default[0]
85:         raise BadRequest unless params.key?(arg.to_sym) || (arg_default.size == 2)
86:         params.key?(arg.to_sym) ? params[arg.to_sym] : arg_default[1]
87:       end rescue []
88:       send(action, *args)
89:     end

call_filters (filter_set)

calls a filter chain according to rules.

     # File lib/merb/abstract_controller.rb, line 92
 92:     def call_filters(filter_set)
 93:       (filter_set || []).each do |(filter, rule)|
 94:         ok = false
 95:         if rule.has_key?(:only)
 96:           if rule[:only].include?(params[:action].intern)
 97:             ok = true
 98:           end
 99:         elsif rule.has_key?(:exclude)
100:           if !rule[:exclude].include?(params[:action].intern)
101:             ok = true
102:           end 
103:         else
104:           ok = true
105:         end    
106:         if ok
107:           case filter
108:             when Symbol, String
109:              send(filter)
110:             when Proc
111:              filter.call(self)
112:           end
113:         end   
114:       end
115:       return :filter_chain_completed
116:     end

content_type ()

     # File lib/merb/abstract_controller.rb, line 233
233:     def content_type
234:       params[:format] || :html
235:     end

content_type_set? ()

Set here to respond when rendering to cover the provides syntax of setting the content_type

     # File lib/merb/abstract_controller.rb, line 229
229:     def content_type_set?
230:       false
231:     end

filters_halted ()

override this method on your controller classes to specialize the output when the filter chain is halted.

     # File lib/merb/abstract_controller.rb, line 136
136:     def filters_halted
137:       "<html><body><h1>Filter Chain Halted!</h1></body></html>"  
138:     end