Class: Merb::Controller

Inherits:
AbstractController show all
Includes:
AuthenticationMixin, Merb::Cache::CacheMixin, ConditionalGetMixin, ControllerMixin, ResponderMixin
Defined in:
merb-core/lib/merb-core/controller/merb_controller.rb,
merb-cache/lib/merb-cache.rb,
merb-param-protection/lib/merb-param-protection.rb

Constant Summary

Constant Summary

Constants included from ResponderMixin

ResponderMixin::ACCEPT_RESULTS, ResponderMixin::MIMES, ResponderMixin::MIME_MUTEX, ResponderMixin::TYPES

Constants inherited from AbstractController

AbstractController::FILTER_OPTIONS

Constants included from ControllerExceptions

Merb::ControllerExceptions::STATUS_CODES

Instance Attribute Summary collapse

Attributes inherited from AbstractController

#_benchmarks, #_thrown_content, #action_name, #body, #content_type

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Merb::Cache::CacheMixin

#_cache_after, #_cache_before, #_eager_cache_after, #_lookup_store, #_parameters_and_conditions, #_set_skip_cache, #default_cache_store, #eager_cache, #fetch_fragment, #fetch_partial, #force_cache!, included, #skip_cache!

Methods included from ConditionalGetMixin

#etag, #etag=, #etag_matches?, #last_modified, #last_modified=, #not_modified?, #request_fresh?

Methods included from AuthenticationMixin

#basic_authentication

Methods included from ControllerMixin

#delete_cookie, #escape_xml, #message, #nginx_send_file, #redirect, #render_chunked, #render_deferred, #render_then_call, #run_later, #send_chunk, #send_data, #send_file, #set_cookie, #stream_file

Methods included from ResponderMixin

#_accept_types, #_perform_content_negotiation, #_provided_formats, #content_type, #content_type=, #does_not_provide, included, #only_provides, #provides

Methods inherited from AbstractController

#_call_action, #_call_filter_for_action?, #_call_filters, #_evaluate_condition, #_filter_condition_met?, _reset_template_roots, _template_root=, _template_roots, _template_roots=, after, before, #capture, #concat, controller_name, #controller_name, old_inherited, skip_after, skip_before

Methods included from RenderMixin

#_get_layout, #_handle_options!, #_template_for, #_template_method_for, #append_content, #catch_content, #clear_content, #display, included, #partial, #render, #throw_content, #thrown_content?

Constructor Details

#initialize(request, status = 200, headers = {'Content-Type' => 'text/html; charset=utf-8'}) ⇒ Controller

Build a new controller.

Sets the variables that came in through the dispatch as available to the controller.

Overridable:



212
213
214
215
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 212

def initialize(request, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
  super()
  @request, @_status, @headers = request, status, headers
end

Instance Attribute Details

#headersObject (readonly)



275
276
277
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 275

def headers
  @headers
end

#requestObject (readonly)



275
276
277
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 275

def request
  @request
end

Class Method Details

._callable_methodsArray

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

All methods that are callable as actions.



152
153
154
155
156
157
158
159
160
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 152

def self._callable_methods
  callables = []
  klass = self
  begin
    callables << (klass.public_instance_methods(false) + klass._shown_actions).map{|m| m.to_s} - klass._hidden_actions
    klass = klass.superclass
  end until klass == Merb::AbstractController || klass == Object
  callables.flatten.reject{|action| action =~ /^_.*/}.map {|x| x.to_s}
end

._filter_params(params) ⇒ Object

Filters parameters so they are not showed in logs.



142
143
144
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 142

def self._filter_params(params)
  params
end

.abstract!Object

Sets a controller to be "abstract".

This controller will not be able to be routed to and is used for super classing only.



371
372
373
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 371

def self.abstract!
  @_abstract = true
end

.abstract?Boolean

Asks a controller if it is abstract



380
381
382
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 380

def self.abstract?
  !!@_abstract 
end

.call(env) ⇒ Array<Integer, Hash, #each>

Call the controller as a Rack endpoint.

Expects: * **env["merb.status"]:** the default status code to be returned * **env["merb.action_name"]:** the action name to dispatch * **env["merb.request_start"]:** a Time object representing the start of the request.



231
232
233
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 231

def self.call(env)
  new(Merb::Request.new(env), env["merb.status"])._call
end

.callable_actionsSimpleSet<String>

The list of actions that are callable, after taking defaults, _hidden_actions and _shown_actions into consideration. It is calculated once, the first time an action is dispatched for this controller.



130
131
132
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 130

def self.callable_actions
  @callable_actions ||= Extlib::SimpleSet.new(_callable_methods)
end

.hide_action(*names) ⇒ Array<String>

Hide each of the given methods from being callable as actions.



91
92
93
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 91

def self.hide_action(*names)
  self._hidden_actions = self._hidden_actions | names.map { |n| n.to_s }
end

.inherited(klass) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



26
27
28
29
30
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 26

def self.inherited(klass)
  _subclasses << klass.to_s
  super
  klass._template_root = Merb.dir_for(:view) unless self._template_root
end

.overridable(*names) ⇒ Array

Returns The list of methods that are overridable



38
39
40
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 38

def self.overridable(*names)
  self._overridable.push(*names)
end

.override!(*names) ⇒ Object

Allow overriding methods.

In an application controller, call override! before a method to indicate that you want to override a method in Merb::Controller that is not normally overridable.

Doing this may potentially break your app in a future release of Merb, and this is provided for users who are willing to take that risk. Without using override!, Merb will raise an error if you attempt to override a method defined on Merb::Controller.

This is to help users avoid a common mistake of defining an action that overrides a core method on Merb::Controller.

class Kontroller < Application
  def status
    render
  end
end

will raise a Merb::ReservedError, because #status is a method on Merb::Controller.

class Kontroller < Application
  override! :status
  def status
    some_code || super
  end
end

will not raise a Merb::ReservedError, because the user specifically decided to override the status method.



79
80
81
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 79

def self.override!(*names)
  self._override_bang.push(*names)
end

.show_action(*names) ⇒ Array<String>

Makes each of the given methods being callable as actions. You can use this to make methods included from modules callable as actions.

Examples:

Use like:

module Foo
  def self.included(base)
    base.show_action(:foo)
  end

  def foo
   # some actiony stuff
  end

  def foo_helper
    # this should not be an action
  end
end


119
120
121
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 119

def self.show_action(*names)
  self._shown_actions = self._shown_actions | names.map {|n| n.to_s}
end

.subclasses_listObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



15
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 15

def self.subclasses_list() _subclasses end

Instance Method Details

#_absolute_template_location(template, type) ⇒ Object

MIME-type aware template locations.

This is overridden from AbstractController, which defines a version that does not involve mime-types.



195
196
197
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 195

def _absolute_template_location(template, type)
  _conditionally_append_extension(template, type)
end

#_callArray<Integer, Hash, #each>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Dispatches the action and records benchmarks



240
241
242
243
244
245
246
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 240

def _call
  _dispatch(request.env["merb.action_name"])
  _benchmarks[:dispatch_time] = Time.now - request.env["merb.request_start"]
  Merb.logger.info { _benchmarks.inspect }
  Merb.logger.flush
  rack_response        
end

#_dispatch(action = :index) ⇒ Merb::Controller

TODO:

See AbstractController#_dispatch and ticket #1335 about the return type.

Dispatch the action.

Extends AbstractController#_dispatch with logging, error handling, and benchmarking.

Raises:



262
263
264
265
266
267
268
269
270
271
272
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 262

def _dispatch(action=:index)
  Merb.logger.info { "Params: #{self.class._filter_params(request.params).inspect}" }
  start = Time.now
  if self.class.callable_actions.include?(action.to_s)
    super(action)
  else
    raise ActionNotFound, "Action '#{action}' was not found in #{self.class}"
  end
  @_benchmarks[:action_time] = Time.now - start
  self
end

#_template_location(context, type, controller) ⇒ Object

MIME-type aware template locations.

This is overridden from AbstractController, which defines a version that does not involve mime-types.

Notes

By default, this renders ":controller/:action.:type". To change this, override it in your application class or in individual controllers.

See Also:

Overridable:



175
176
177
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 175

def _template_location(context, type, controller)
  _conditionally_append_extension(controller ? "#{controller}/#{context}" : "#{context}", type)
end

#absolute_url(*args) ⇒ Object

Returns the absolute URL including the passed protocol and host.

Calls AbstractController#absolute_url with the protocol and host options pre-populated from the current request unless explicitly specified.



347
348
349
350
351
352
353
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 347

def absolute_url(*args)
  options  = extract_options_from_args!(args) || {}
  options[:protocol] ||= request.protocol
  options[:host] ||= request.host
  args << options
  super(*args)
end

#paramsHash

The parameters from the request object.



306
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 306

def params()  request.params  end

#rack_responseArray<Integer, Hash, String>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The results of the controller's render, to be returned to Rack.



361
362
363
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 361

def rack_response
  [status, headers, Merb::Rack::StreamWrapper.new(body)]
end

#resource(*args) ⇒ Object

Generates a URL for a single or nested resource.

Same as Router.resource, but all parameters of the current request are also added to the arguments.

See Also:



331
332
333
334
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 331

def resource(*args)
  args << params
  Merb::Router.resource(*args)
end

#statusFixnum

Response status code.



282
283
284
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 282

def status
  @_status
end

#status=(s) ⇒ Object

Set the response status code.



291
292
293
294
295
296
297
298
299
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 291

def status=(s)
  if s.is_a?(Symbol) && STATUS_CODES.key?(s)
    @_status = STATUS_CODES[s]
  elsif s.is_a?(Fixnum)
    @_status = s
  else
    raise ArgumentError, "Status should be of type Fixnum or Symbol, was #{s.class}"
  end
end

#url(name, *args) ⇒ Object Also known as: relative_url

Generate URLs.

Same as Router.url, but allows to pass :this as a name to use the name of the current Request. All parameters of the current request are also added to the arguments.

See Also:



317
318
319
320
321
# File 'merb-core/lib/merb-core/controller/merb_controller.rb', line 317

def url(name, *args)
  args << params
  name = request.route if name == :this
  Merb::Router.url(name, *args)
end