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

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

Build a new controller.

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

Parameters:

  • request (Merb::Request)

    The Merb::Request that came in from Rack.

  • status (Integer) (defaults to: 200)

    An integer code for the status.

  • headers (Hash<header => value>) (defaults to: {'Content-Type' => 'text/html; charset=utf-8'})

    A hash of headers to start the controller with. These headers can be overridden later by the #headers method.

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

- (Object) headers (readonly)



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

def headers
  @headers
end

- (Object) request (readonly)



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

def request
  @request
end

Class Method Details

+ (Array) _callable_methods

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.

Returns:

  • (Array)

    A list of method names that are also 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

+ (Object) _filter_params(params)

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

+ (Object) abstract!

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

+ (Boolean) abstract?

Asks a controller if it is abstract

Returns:

  • (Boolean)

    True if the controller has been set as abstract.



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

def self.abstract?
  !!@_abstract 
end

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

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.

Parameters:

  • env (Hash)

    A rack environment

Returns:

  • (Array<Integer, Hash, #each>)

    A standard Rack response



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

+ (SimpleSet<String>) callable_actions

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.

Returns:

  • (SimpleSet<String>)

    Actions that should be callable.



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

+ (Array<String>) hide_action(*names)

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

Parameters:

  • *names (Array<#to_s>)

    Actions that should be added to the list.

Returns:

  • (Array<String>)

    Actions that should not be possible to dispatch to.



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

+ (Object) inherited(klass)

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.

Parameters:

  • klass (Merb::Controller)

    The Merb::Controller inheriting from the base class.



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

+ (Array) overridable(*names)

Returns The list of methods that are overridable

Parameters:

  • *names (Array<Symbol>)

    Array of method names that should be overridable in application controllers.

Returns:

  • (Array)

    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

+ (Object) override!(*names)

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.

Parameters:

  • *names (Array<Symbol>)

    An Array of methods that will override Merb core classes on purpose



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

+ (Array<String>) show_action(*names)

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

Parameters:

  • *names (Array<#to_s>)

    Actions that should be added to the list.

Returns:

  • (Array<String>)

    Actions that should be dispatched to even if they would not otherwise be.



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

+ (Object) subclasses_list

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

- (Object) _absolute_template_location(template, type)

MIME-type aware template locations.

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

Parameters:

  • template (String)

    The absolute path to a template, without mime type and template extension. The mime-type extension is optional and will be appended from the current content type if it hasn't been added already.

  • type (#to_s)

    The mime-type of the template that will be rendered. Defaults to nil.

See Also:



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

- (Array<Integer, Hash, #each>) _call

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

Returns:

  • (Array<Integer, Hash, #each>)

    A standard Rack response



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

- (Merb::Controller) _dispatch(action = :index)

TODO:

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

Dispatch the action.

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

Parameters:

  • action (#to_s) (defaults to: :index)

    The action to dispatch to.

Returns:

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

- (Object) _template_location(context, type, controller)

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

- (Object) absolute_url(*args)

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

- (Hash) params

The parameters from the request object.

Returns:



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

def params()  request.params  end

- (Array<Integer, Hash, String>) rack_response

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.

Returns:

  • (Array<Integer, Hash, String>)

    The controller's status code, headers, and body



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

- (Object) resource(*args)

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

- (Fixnum) status

Response status code.

Returns:

  • (Fixnum)


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

def status
  @_status
end

- (Object) status=(s)

Set the response status code.

Parameters:

  • s (Fixnum, Symbol)

    A status code or named HTTP status



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

- (Object) url(name, *args) 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