Class: Rory::Controller

Inherits:
Object
  • Object
show all
Includes:
PathGeneration
Defined in:
lib/rory/controller.rb

Overview

Interface for Controller class. Subclass this to create controllers with actions that will be called by the Dispatcher when a route matches.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PathGeneration

#path_to

Constructor Details

#initialize(request, routing, app = nil) ⇒ Controller

Returns a new instance of Controller.



42
43
44
45
46
47
48
49
# 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

Instance Attribute Details

#dispatcherObject (readonly)

Returns the value of attribute dispatcher.



11
12
13
# File 'lib/rory/controller.rb', line 11

def dispatcher
  @dispatcher
end

#localsObject

Returns the value of attribute locals.



10
11
12
# File 'lib/rory/controller.rb', line 10

def locals
  @locals
end

Class Method Details

.after_action(method_name, opts = {}) ⇒ Object

Register a method to run after the action method.



28
29
30
# File 'lib/rory/controller.rb', line 28

def after_action(method_name, opts = {})
  after_actions << opts.merge(:method_name => method_name)
end

.after_actionsObject



18
19
20
# File 'lib/rory/controller.rb', line 18

def after_actions
  @after_actions ||= ancestor_actions(:after)
end

.ancestor_actions(action_type) ⇒ Object



32
33
34
35
36
37
38
39
# 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 = {}) ⇒ Object

Register a method to run before the action method.



23
24
25
# File 'lib/rory/controller.rb', line 23

def before_action(method_name, opts = {})
  before_actions << opts.merge(:method_name => method_name)
end

.before_actionsObject



14
15
16
# File 'lib/rory/controller.rb', line 14

def before_actions
  @before_actions ||= ancestor_actions(:before)
end

Instance Method Details

#base_pathObject



74
75
76
# File 'lib/rory/controller.rb', line 74

def base_path
  @request.script_name
end

#default_content_type(opts = {}) ⇒ Object



139
140
141
142
143
144
145
# 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_optionsObject



78
79
80
81
82
83
84
85
# File 'lib/rory/controller.rb', line 78

def default_renderer_options
  {
    :layout => layout,
    :locals => locals,
    :app => @app,
    :base_path => base_path
  }
end

#expose(hsh) ⇒ Object



55
56
57
# File 'lib/rory/controller.rb', line 55

def expose(hsh)
  locals.merge!(hsh)
end

#extract_options(options_or_template, opts = {}) ⇒ Object



87
88
89
90
91
92
93
# 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 = {}) ⇒ Object



125
126
127
128
129
# 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 = {}) ⇒ Object



115
116
117
118
119
120
121
122
123
# 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 = {}) ⇒ Object



111
112
113
# File 'lib/rory/controller.rb', line 111

def generate_json_from_object(object, opts = {})
  Rory::Support.encode_as_json(object)
end

#json_requested?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/rory/controller.rb', line 51

def json_requested?
  dispatcher.json_requested?
end

#layoutObject



70
71
72
# File 'lib/rory/controller.rb', line 70

def layout
  nil
end

#paramsObject



59
60
61
62
63
64
# 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

#presentObject



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# 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) ⇒ Object



131
132
133
# File 'lib/rory/controller.rb', line 131

def redirect(path)
  @response = dispatcher.redirect(path)
end

#render(options_or_template = nil, opts = {}) ⇒ Object



104
105
106
107
108
109
# 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_foundObject



135
136
137
# File 'lib/rory/controller.rb', line 135

def render_not_found
  @response = dispatcher.render_not_found
end

#route_templateObject



66
67
68
# File 'lib/rory/controller.rb', line 66

def route_template
  "#{@route.controller}/#{@route.action}"
end

#set_response_defaults(opts) ⇒ Object



95
96
97
98
99
100
101
102
# 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