class Rory::Controller
Interface for Controller
class. Subclass this to create controllers with actions that will be called by the Dispatcher
when a route matches.
Attributes
dispatcher[R]
locals[RW]
Public Class Methods
after_action(method_name, opts = {})
click to toggle source
Register a method to run after the action method.
# File lib/rory/controller.rb, line 28 def after_action(method_name, opts = {}) after_actions << opts.merge(:method_name => method_name) end
after_actions()
click to toggle source
# File lib/rory/controller.rb, line 18 def after_actions @after_actions ||= ancestor_actions(:after) end
ancestor_actions(action_type)
click to toggle source
# File lib/rory/controller.rb, line 32 def ancestor_actions(action_type) query_method = :"#{action_type}_actions" if superclass && superclass.respond_to?(query_method) superclass.send(query_method).flatten.compact else [] end end
before_action(method_name, opts = {})
click to toggle source
Register a method to run before the action method.
# File lib/rory/controller.rb, line 23 def before_action(method_name, opts = {}) before_actions << opts.merge(:method_name => method_name) end
before_actions()
click to toggle source
# File lib/rory/controller.rb, line 14 def before_actions @before_actions ||= ancestor_actions(:before) end
new(request, routing, app = nil)
click to toggle source
# File lib/rory/controller.rb, line 42 def initialize(request, routing, app = nil) @request = request @dispatcher = routing[:dispatcher] @route = routing[:route] @params = request.params @app = app @locals = {} end
Public Instance Methods
base_path()
click to toggle source
# File lib/rory/controller.rb, line 74 def base_path @request.script_name end
default_content_type(opts = {})
click to toggle source
# File lib/rory/controller.rb, line 139 def default_content_type(opts = {}) if json_requested? || opts[:json] 'application/json' else 'text/html' end end
default_renderer_options()
click to toggle source
# File lib/rory/controller.rb, line 78 def default_renderer_options { :layout => layout, :locals => locals, :app => @app, :base_path => base_path } end
expose(hsh)
click to toggle source
# File lib/rory/controller.rb, line 55 def expose(hsh) locals.merge!(hsh) end
extract_options(options_or_template, opts = {})
click to toggle source
# File lib/rory/controller.rb, line 87 def extract_options(options_or_template, opts = {}) if options_or_template.is_a?(Hash) options_or_template else opts.merge(:template => options_or_template) end end
generate_body_from_template(template_name, opts = {})
click to toggle source
# File lib/rory/controller.rb, line 125 def generate_body_from_template(template_name, opts = {}) opts = default_renderer_options.merge(opts) renderer = Rory::Renderer.new(template_name, opts) renderer.render end
generate_for_render(opts = {})
click to toggle source
# File lib/rory/controller.rb, line 115 def generate_for_render(opts = {}) object, template = opts.delete(:json), opts.delete(:template) if object generate_json_from_object(object, opts) else template ||= route_template generate_body_from_template(template, opts) end end
generate_json_from_object(object, opts = {})
click to toggle source
# File lib/rory/controller.rb, line 111 def generate_json_from_object(object, opts = {}) Rory::Support.encode_as_json(object) end
json_requested?()
click to toggle source
# File lib/rory/controller.rb, line 51 def json_requested? dispatcher.json_requested? end
layout()
click to toggle source
# File lib/rory/controller.rb, line 70 def layout nil end
params()
click to toggle source
# File lib/rory/controller.rb, line 59 def params @converted_params ||= @params.inject({}) { |memo, (key, value)| memo[key.to_sym] = memo[key.to_s] = value memo } end
present()
click to toggle source
# File lib/rory/controller.rb, line 147 def present # Call all before and after filters, and if a method exists on the # controller for the requested action, call it in between. call_filtered_action(@route.action.to_sym) if @response # that method may have resulted in a response already being generated # (such as a redirect, or 404, or other non-HTML response). if so, # just return that response. @response else # even if there wasn't a full response generated, we might already have # a @body, if @body was explicitly assigned for some reason. # don't render the default template, in that case. render(:body => @body) end end
redirect(path)
click to toggle source
# File lib/rory/controller.rb, line 131 def redirect(path) @response = dispatcher.redirect(path) end
render(options_or_template = nil, opts = {})
click to toggle source
# File lib/rory/controller.rb, line 104 def render(options_or_template = nil, opts = {}) opts = extract_options(options_or_template, opts) set_response_defaults(opts) opts[:body] ||= generate_for_render(opts) @response = [opts[:status], opts[:headers], [opts[:body]]] end
render_not_found()
click to toggle source
# File lib/rory/controller.rb, line 135 def render_not_found @response = dispatcher.render_not_found end
route_template()
click to toggle source
# File lib/rory/controller.rb, line 66 def route_template "#{@route.controller}/#{@route.action}" end
set_response_defaults(opts)
click to toggle source
# File lib/rory/controller.rb, line 95 def set_response_defaults(opts) opts[:content_type] ||= default_content_type(opts) opts[:status] ||= 200 opts[:headers] = { 'Content-type' => opts[:content_type], 'charset' => 'UTF-8' }.merge(opts[:headers] || {}) end
Private Instance Methods
assess_filter_condition(condition)
click to toggle source
# File lib/rory/controller.rb, line 185 def assess_filter_condition(condition) case condition when Symbol self.send(condition) when Proc instance_exec(&condition) end end
call_filter_for_action?(filter, action)
click to toggle source
# File lib/rory/controller.rb, line 167 def call_filter_for_action?(filter, action) (filter[:only].nil? || filter[:only].include?(action)) && (filter[:except].nil? || !filter[:except].include?(action)) && filter_conditions_pass?(filter, :if) && filter_conditions_pass?(filter, :unless) end
call_filter_set(which_set, action, opts = {})
click to toggle source
# File lib/rory/controller.rb, line 199 def call_filter_set(which_set, action, opts = {}) opts = { :break_if_response => true }.merge(opts) filters = get_relevant_filters(which_set, action) filters.each do |filter| break if @response && opts[:break_if_response] self.send(filter[:method_name]) end end
call_filtered_action(action)
click to toggle source
# File lib/rory/controller.rb, line 208 def call_filtered_action(action) call_filter_set(:before_actions, action) unless @response self.send(action) if self.respond_to?(action) call_filter_set(:after_actions, action, :break_if_response => false) end end
filter_conditions_pass?(filter, type)
click to toggle source
# File lib/rory/controller.rb, line 174 def filter_conditions_pass?(filter, type) filter_conditions = Array(filter[type]) filter_conditions.compact.all? { |condition| result = assess_filter_condition(condition) if type == :unless result = !result end result } end
get_relevant_filters(which_set, action)
click to toggle source
# File lib/rory/controller.rb, line 194 def get_relevant_filters(which_set, action) filters = self.class.send(which_set) filters.select { |filter| call_filter_for_action?(filter, action) } end