Class: Merb::AbstractController
Attributes
| Name | Read/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