aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/abstract/renderer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller/abstract/renderer.rb')
-rw-r--r--actionpack/lib/action_controller/abstract/renderer.rb37
1 files changed, 26 insertions, 11 deletions
diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb
index b5c31a27ee..b58688c9da 100644
--- a/actionpack/lib/action_controller/abstract/renderer.rb
+++ b/actionpack/lib/action_controller/abstract/renderer.rb
@@ -1,6 +1,15 @@
require "action_controller/abstract/logger"
module AbstractController
+ class AbstractControllerError < StandardError; end
+ class DoubleRenderError < AbstractControllerError
+ DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
+
+ def initialize(message = nil)
+ super(message || DEFAULT_MESSAGE)
+ end
+ end
+
module Renderer
extend ActiveSupport::DependencyModule
@@ -15,31 +24,36 @@ module AbstractController
end
def _action_view
- @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
+ @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
end
-
+
def render(options = {})
+ if response_body
+ raise AbstractController::DoubleRenderError, "OMG"
+ end
+
self.response_body = render_to_body(options)
end
-
+
# Raw rendering of a template to a Rack-compatible body.
# ====
# @option _prefix<String> The template's path prefix
# @option _layout<String> The relative path to the layout template to use
- #
+ #
# :api: plugin
def render_to_body(options = {})
name = options[:_template_name] || action_name
-
- template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix])
- _render_template(template, options)
+
+ options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix])
+
+ _render_template(options[:_template], options)
end
# Raw rendering of a template to a string.
# ====
# @option _prefix<String> The template's path prefix
# @option _layout<String> The relative path to the layout template to use
- #
+ #
# :api: plugin
def render_to_string(options = {})
AbstractController::Renderer.body_to_s(render_to_body(options))
@@ -48,7 +62,7 @@ module AbstractController
def _render_template(template, options)
_action_view._render_template_with_layout(template)
end
-
+
def view_paths() _view_paths end
# Return a string representation of a Rack-compatible response body.
@@ -64,14 +78,15 @@ module AbstractController
end
module ClassMethods
+
def append_view_path(path)
self.view_paths << path
end
-
+
def view_paths
self._view_paths
end
-
+
def view_paths=(paths)
self._view_paths = paths.is_a?(ActionView::PathSet) ?
paths : ActionView::Base.process_view_paths(paths)