mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
parent
dd98280e38
commit
de203245af
23 changed files with 272 additions and 266 deletions
|
@ -11,4 +11,4 @@ module AbstractController
|
|||
autoload :Renderer, "action_controller/abstract/renderer"
|
||||
# === Exceptions
|
||||
autoload :ActionNotFound, "action_controller/abstract/exceptions"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,28 +2,27 @@ require 'active_support/core_ext/module/attr_internal'
|
|||
|
||||
module AbstractController
|
||||
class Error < StandardError; end
|
||||
|
||||
|
||||
class DoubleRenderError < Error
|
||||
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
|
||||
|
||||
end
|
||||
|
||||
class Base
|
||||
|
||||
attr_internal :response_body
|
||||
attr_internal :response_obj
|
||||
attr_internal :action_name
|
||||
|
||||
class << self
|
||||
attr_reader :abstract
|
||||
|
||||
attr_reader :abstract
|
||||
|
||||
def abstract!
|
||||
@abstract = true
|
||||
end
|
||||
|
||||
|
||||
alias_method :abstract?, :abstract
|
||||
|
||||
def inherited(klass)
|
||||
|
@ -34,13 +33,13 @@ module AbstractController
|
|||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
|
||||
def internal_methods
|
||||
controller = self
|
||||
controller = controller.superclass until controller.abstract?
|
||||
controller.public_instance_methods(true)
|
||||
end
|
||||
|
||||
|
||||
def process(action)
|
||||
new.process(action.to_s)
|
||||
end
|
||||
|
@ -48,7 +47,7 @@ module AbstractController
|
|||
def hidden_actions
|
||||
[]
|
||||
end
|
||||
|
||||
|
||||
def action_methods
|
||||
@action_methods ||=
|
||||
# All public instance methods of this class, including ancestors
|
||||
|
@ -61,13 +60,13 @@ module AbstractController
|
|||
hidden_actions
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
abstract!
|
||||
|
||||
|
||||
def initialize
|
||||
self.response_obj = {}
|
||||
end
|
||||
|
||||
|
||||
def process(action)
|
||||
@_action_name = action_name = action.to_s
|
||||
|
||||
|
@ -78,17 +77,16 @@ module AbstractController
|
|||
process_action(action_name)
|
||||
self
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def action_methods
|
||||
self.class.action_methods
|
||||
end
|
||||
|
||||
|
||||
def action_method?(action)
|
||||
action_methods.include?(action)
|
||||
end
|
||||
|
||||
|
||||
# It is possible for respond_to?(action_name) to be false and
|
||||
# respond_to?(:action_missing) to be false if respond_to_action?
|
||||
# is overridden in a subclass. For instance, ActionController::Base
|
||||
|
@ -114,4 +112,4 @@ module AbstractController
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module AbstractController
|
||||
module Benchmarker
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
|
||||
depends_on Logger
|
||||
|
||||
|
||||
module ClassMethods
|
||||
def benchmark(title, log_level = ::Logger::DEBUG, use_silence = true)
|
||||
if logger && logger.level >= log_level
|
||||
|
@ -25,4 +25,4 @@ module AbstractController
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ module AbstractController
|
|||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module ClassMethods
|
||||
def _normalize_callback_options(options)
|
||||
if only = options[:only]
|
||||
|
@ -21,11 +21,11 @@ module AbstractController
|
|||
options[:per_key] = {:if => only}
|
||||
end
|
||||
if except = options[:except]
|
||||
except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
|
||||
except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
|
||||
options[:per_key] = {:unless => except}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
[:before, :after, :around].each do |filter|
|
||||
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
||||
def #{filter}_filter(*names, &blk)
|
||||
|
@ -60,4 +60,4 @@ module AbstractController
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module AbstractController
|
||||
class ActionNotFound < StandardError ; end
|
||||
end
|
||||
class ActionNotFound < StandardError; end
|
||||
end
|
||||
|
|
|
@ -16,12 +16,12 @@ module AbstractController
|
|||
av
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module ClassMethods
|
||||
def inherited(klass)
|
||||
klass.master_helper_module = Module.new
|
||||
klass.master_helper_module.__send__ :include, master_helper_module
|
||||
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
|
@ -57,7 +57,7 @@ module AbstractController
|
|||
ruby_eval
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def helper(*args, &block)
|
||||
args.flatten.each do |arg|
|
||||
case arg
|
||||
|
@ -68,6 +68,5 @@ module AbstractController
|
|||
master_helper_module.module_eval(&block) if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,18 +17,18 @@ module AbstractController
|
|||
|
||||
conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
|
||||
self._layout_conditions = conditions
|
||||
|
||||
|
||||
@_layout = layout || false # Converts nil to false
|
||||
_write_layout_method
|
||||
end
|
||||
|
||||
|
||||
def _implied_layout_name
|
||||
name.underscore
|
||||
end
|
||||
|
||||
|
||||
# Takes the specified layout and creates a _layout method to be called
|
||||
# by _default_layout
|
||||
#
|
||||
#
|
||||
# If the specified layout is a:
|
||||
# String:: return the string
|
||||
# Symbol:: call the method specified by the symbol
|
||||
|
@ -57,11 +57,12 @@ module AbstractController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def _layout(details) end # This will be overwritten
|
||||
|
||||
# This will be overwritten
|
||||
def _layout(details)
|
||||
end
|
||||
|
||||
# :api: plugin
|
||||
# ====
|
||||
# Override this to mutate the inbound layout name
|
||||
|
@ -69,7 +70,7 @@ module AbstractController
|
|||
unless [String, FalseClass, NilClass].include?(name.class)
|
||||
raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
|
||||
end
|
||||
|
||||
|
||||
name && view_paths.find_by_parts(name, details, _layout_prefix(name))
|
||||
end
|
||||
|
||||
|
@ -77,7 +78,7 @@ module AbstractController
|
|||
def _layout_prefix(name)
|
||||
"layouts"
|
||||
end
|
||||
|
||||
|
||||
def _default_layout(require_layout = false, details = {:formats => formats})
|
||||
if require_layout && _action_has_layout? && !_layout(details)
|
||||
raise ArgumentError,
|
||||
|
@ -87,7 +88,7 @@ module AbstractController
|
|||
begin
|
||||
_layout_for_name(_layout(details), details) if _action_has_layout?
|
||||
rescue NameError => e
|
||||
raise NoMethodError,
|
||||
raise NoMethodError,
|
||||
"You specified #{@_layout.inspect} as the layout, but no such method was found"
|
||||
end
|
||||
end
|
||||
|
@ -103,4 +104,4 @@ module AbstractController
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module AbstractController
|
|||
def initialize(&blk)
|
||||
@blk = blk
|
||||
end
|
||||
|
||||
|
||||
def to_s
|
||||
@blk.call
|
||||
end
|
||||
|
@ -19,10 +19,10 @@ module AbstractController
|
|||
included do
|
||||
cattr_accessor :logger
|
||||
end
|
||||
|
||||
|
||||
def process(action)
|
||||
ret = super
|
||||
|
||||
|
||||
if logger
|
||||
log = DelayedLog.new do
|
||||
"\n\nProcessing #{self.class.name}\##{action_name} " \
|
||||
|
@ -32,14 +32,14 @@ module AbstractController
|
|||
|
||||
logger.info(log)
|
||||
end
|
||||
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
|
||||
def request_origin
|
||||
# this *needs* to be cached!
|
||||
# otherwise you'd get different results if calling it more than once
|
||||
@request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,22 +15,22 @@ 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(*args)
|
||||
if response_body
|
||||
raise AbstractController::DoubleRenderError, "OMG"
|
||||
end
|
||||
|
||||
|
||||
self.response_body = render_to_body(*args)
|
||||
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 = {})
|
||||
# TODO: Refactor so we can just use the normal template logic for this
|
||||
|
@ -46,7 +46,7 @@ module AbstractController
|
|||
# ====
|
||||
# @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))
|
||||
|
@ -55,8 +55,10 @@ module AbstractController
|
|||
def _render_template(options)
|
||||
_action_view._render_template_from_controller(options[:_template], options[:_layout], options, options[:_partial])
|
||||
end
|
||||
|
||||
def view_paths() _view_paths end
|
||||
|
||||
def view_paths()
|
||||
_view_paths
|
||||
end
|
||||
|
||||
# Return a string representation of a Rack-compatible response body.
|
||||
def self.body_to_s(body)
|
||||
|
@ -71,7 +73,6 @@ module AbstractController
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def _determine_template(options)
|
||||
name = (options[:_template_name] || action_name).to_s
|
||||
|
||||
|
@ -81,11 +82,10 @@ module AbstractController
|
|||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
def append_view_path(path)
|
||||
self.view_paths << path
|
||||
end
|
||||
|
||||
|
||||
def prepend_view_path(path)
|
||||
self.view_paths.unshift(path)
|
||||
end
|
||||
|
@ -93,7 +93,7 @@ module AbstractController
|
|||
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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module ActionController
|
||||
class Base < Http
|
||||
abstract!
|
||||
|
||||
|
||||
include AbstractController::Benchmarker
|
||||
include AbstractController::Callbacks
|
||||
include AbstractController::Logger
|
||||
|
@ -66,31 +66,31 @@ module ActionController
|
|||
::ActionController::Base.subclasses << klass.to_s
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
def self.subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
|
||||
def self.app_loaded!
|
||||
@subclasses.each do |subclass|
|
||||
subclass.constantize._write_layout_method
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def _normalize_options(action = nil, options = {}, &blk)
|
||||
if action.is_a?(Hash)
|
||||
options, action = action, nil
|
||||
options, action = action, nil
|
||||
elsif action.is_a?(String) || action.is_a?(Symbol)
|
||||
key = case action = action.to_s
|
||||
when %r{^/} then :file
|
||||
when %r{/} then :template
|
||||
else :action
|
||||
end
|
||||
end
|
||||
options.merge! key => action
|
||||
elsif action
|
||||
options.merge! :partial => action
|
||||
end
|
||||
|
||||
|
||||
if options.key?(:action) && options[:action].to_s.index("/")
|
||||
options[:template] = options.delete(:action)
|
||||
end
|
||||
|
@ -140,7 +140,7 @@ module ActionController
|
|||
#
|
||||
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
||||
# RedirectBackError will be raised. You may specify some fallback
|
||||
# behavior for this case by rescuing RedirectBackError.
|
||||
# behavior for this case by rescuing RedirectBackError.
|
||||
def redirect_to(options = {}, response_status = {}) #:doc:
|
||||
raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
|
||||
|
||||
|
@ -166,7 +166,7 @@ module ActionController
|
|||
else
|
||||
url_for(options)
|
||||
end
|
||||
|
||||
|
||||
super(url, status)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,43 +9,43 @@ module ActionController
|
|||
included do
|
||||
::ActionController::UnknownAction = ::AbstractController::ActionNotFound
|
||||
::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError
|
||||
|
||||
|
||||
cattr_accessor :session_options
|
||||
self.session_options = {}
|
||||
|
||||
|
||||
cattr_accessor :allow_concurrency
|
||||
self.allow_concurrency = false
|
||||
|
||||
|
||||
cattr_accessor :param_parsers
|
||||
self.param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
|
||||
Mime::URL_ENCODED_FORM => :url_encoded_form,
|
||||
Mime::XML => :xml_simple,
|
||||
Mime::JSON => :json }
|
||||
|
||||
|
||||
cattr_accessor :relative_url_root
|
||||
self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
|
||||
|
||||
|
||||
cattr_accessor :default_charset
|
||||
self.default_charset = "utf-8"
|
||||
|
||||
|
||||
# cattr_reader :protected_instance_variables
|
||||
cattr_accessor :protected_instance_variables
|
||||
self.protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
|
||||
@action_name @before_filter_chain_aborted @action_cache_path @_headers @_params
|
||||
@_flash @_response)
|
||||
|
||||
|
||||
# Indicates whether or not optimise the generated named
|
||||
# route helper methods
|
||||
cattr_accessor :optimise_named_routes
|
||||
self.optimise_named_routes = true
|
||||
|
||||
|
||||
cattr_accessor :resources_path_names
|
||||
self.resources_path_names = { :new => 'new', :edit => 'edit' }
|
||||
|
||||
|
||||
# Controls the resource action separator
|
||||
cattr_accessor :resource_action_separator
|
||||
self.resource_action_separator = "/"
|
||||
|
||||
|
||||
cattr_accessor :use_accept_header
|
||||
self.use_accept_header = true
|
||||
|
||||
|
@ -65,7 +65,7 @@ module ActionController
|
|||
cattr_accessor :ip_spoofing_check
|
||||
self.ip_spoofing_check = true
|
||||
end
|
||||
|
||||
|
||||
# For old tests
|
||||
def initialize_template_class(*) end
|
||||
def assign_shortcuts(*) end
|
||||
|
@ -81,7 +81,9 @@ module ActionController
|
|||
end
|
||||
|
||||
module ClassMethods
|
||||
def consider_all_requests_local() end
|
||||
def consider_all_requests_local
|
||||
end
|
||||
|
||||
def rescue_action(env)
|
||||
raise env["action_dispatch.rescue.exception"]
|
||||
end
|
||||
|
@ -91,12 +93,12 @@ module ActionController
|
|||
@@cache_store = ActiveSupport::Cache.lookup_store(store_option)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def render_to_body(options)
|
||||
if options.is_a?(Hash) && options.key?(:template)
|
||||
options[:template].sub!(/^\//, '')
|
||||
end
|
||||
|
||||
|
||||
options[:text] = nil if options[:nothing] == true
|
||||
|
||||
body = super
|
||||
|
@ -110,8 +112,8 @@ module ActionController
|
|||
|
||||
def method_for_action(action_name)
|
||||
super || (respond_to?(:method_missing) && "_handle_method_missing")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def _layout_prefix(name)
|
||||
super unless name =~ /\blayouts/
|
||||
end
|
||||
|
|
|
@ -3,13 +3,13 @@ module ActionController
|
|||
extend ActiveSupport::DependencyModule
|
||||
|
||||
depends_on RackConvenience
|
||||
|
||||
|
||||
# Sets the etag, last_modified, or both on the response and renders a
|
||||
# "304 Not Modified" response if the request is already fresh.
|
||||
#
|
||||
# Parameters:
|
||||
# * <tt>:etag</tt>
|
||||
# * <tt>:last_modified</tt>
|
||||
# * <tt>:last_modified</tt>
|
||||
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
|
||||
#
|
||||
# Example:
|
||||
|
@ -21,14 +21,14 @@ module ActionController
|
|||
#
|
||||
# This will render the show template if the request isn't sending a matching etag or
|
||||
# If-Modified-Since header and just a "304 Not Modified" response if there's a match.
|
||||
#
|
||||
#
|
||||
def fresh_when(options)
|
||||
options.assert_valid_keys(:etag, :last_modified, :public)
|
||||
|
||||
response.etag = options[:etag] if options[:etag]
|
||||
response.last_modified = options[:last_modified] if options[:last_modified]
|
||||
|
||||
if options[:public]
|
||||
|
||||
if options[:public]
|
||||
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
|
||||
cache_control.delete("private")
|
||||
cache_control.delete("no-cache")
|
||||
|
@ -39,8 +39,8 @@ module ActionController
|
|||
if request.fresh?(response)
|
||||
head :not_modified
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Return a response that has no content (merely headers). The options
|
||||
# argument is interpreted to be a hash of header names and values.
|
||||
# This allows you to easily return a response that consists only of
|
||||
|
@ -67,8 +67,8 @@ module ActionController
|
|||
end
|
||||
|
||||
render :nothing => true, :status => status
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Sets the etag and/or last_modified on the response and checks it against
|
||||
# the client request. If the request doesn't match the options provided, the
|
||||
# request is considered stale and should be generated from scratch. Otherwise,
|
||||
|
@ -76,7 +76,7 @@ module ActionController
|
|||
#
|
||||
# Parameters:
|
||||
# * <tt>:etag</tt>
|
||||
# * <tt>:last_modified</tt>
|
||||
# * <tt>:last_modified</tt>
|
||||
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
|
||||
#
|
||||
# Example:
|
||||
|
@ -95,7 +95,7 @@ module ActionController
|
|||
fresh_when(options)
|
||||
!request.fresh?(response)
|
||||
end
|
||||
|
||||
|
||||
# Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a "private" instruction, so that
|
||||
# intermediate caches shouldn't cache the response.
|
||||
#
|
||||
|
@ -117,10 +117,10 @@ module ActionController
|
|||
else
|
||||
cache_control << "private"
|
||||
end
|
||||
|
||||
|
||||
# This allows for additional headers to be passed through like 'max-stale' => 5.hours
|
||||
cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
|
||||
|
||||
|
||||
response.headers["Cache-Control"] = cache_control.join(', ')
|
||||
end
|
||||
|
||||
|
@ -129,6 +129,5 @@ module ActionController
|
|||
def expires_now #:doc:
|
||||
response.headers["Cache-Control"] = "no-cache"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,10 +24,10 @@ module ActionController
|
|||
#
|
||||
# * <tt>*args</tt>: One or more modules, strings or symbols, or the special symbol <tt>:all</tt>.
|
||||
# * <tt>&block</tt>: A block defining helper methods.
|
||||
#
|
||||
#
|
||||
# ==== Examples
|
||||
# When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
|
||||
# and include the module in the template class. The second form illustrates how to include custom helpers
|
||||
# When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
|
||||
# and include the module in the template class. The second form illustrates how to include custom helpers
|
||||
# when working with namespaced controllers, or other cases where the file containing the helper definition is not
|
||||
# in one of Rails' standard load paths:
|
||||
# helper :foo # => requires 'foo_helper' and includes FooHelper
|
||||
|
@ -40,17 +40,17 @@ module ActionController
|
|||
# <tt>ActionController::Base.helpers_dir</tt> (defaults to <tt>app/helpers/**/*.rb</tt> under RAILS_ROOT).
|
||||
# helper :all
|
||||
#
|
||||
# Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
|
||||
# Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
|
||||
# to the template.
|
||||
# # One line
|
||||
# helper { def hello() "Hello, world!" end }
|
||||
# # Multi-line
|
||||
# helper do
|
||||
# def foo(bar)
|
||||
# "#{bar} is the very best"
|
||||
# def foo(bar)
|
||||
# "#{bar} is the very best"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
|
||||
# +symbols+, +strings+, +modules+ and blocks.
|
||||
# helper(:three, BlindHelper) { def mice() 'mice' end }
|
||||
|
@ -106,25 +106,24 @@ module ActionController
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def default_helper_module!
|
||||
unless name.blank?
|
||||
module_name = name.sub(/Controller$|$/, 'Helper')
|
||||
module_path = module_name.split('::').map { |m| m.underscore }.join('/')
|
||||
require_dependency module_path
|
||||
helper module_name.constantize
|
||||
def default_helper_module!
|
||||
unless name.blank?
|
||||
module_name = name.sub(/Controller$|$/, 'Helper')
|
||||
module_path = module_name.split('::').map { |m| m.underscore }.join('/')
|
||||
require_dependency module_path
|
||||
helper module_name.constantize
|
||||
end
|
||||
rescue MissingSourceFile => e
|
||||
raise unless e.is_missing? module_path
|
||||
rescue NameError => e
|
||||
raise unless e.missing_name? module_name
|
||||
end
|
||||
rescue MissingSourceFile => e
|
||||
raise unless e.is_missing? module_path
|
||||
rescue NameError => e
|
||||
raise unless e.missing_name? module_name
|
||||
end
|
||||
|
||||
# Extract helper names from files in app/helpers/**/*.rb
|
||||
def all_application_helpers
|
||||
extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/
|
||||
Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
|
||||
end
|
||||
end # ClassMethods
|
||||
# Extract helper names from files in app/helpers/**/*.rb
|
||||
def all_application_helpers
|
||||
extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/
|
||||
Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,27 +7,33 @@ module ActionController
|
|||
self.hidden_actions ||= Set.new
|
||||
end
|
||||
|
||||
def action_methods() self.class.action_names end
|
||||
def action_names() action_methods end
|
||||
|
||||
private
|
||||
|
||||
def action_method?(action_name)
|
||||
!hidden_actions.include?(action_name) && super
|
||||
def action_methods
|
||||
self.class.action_names
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def hide_action(*args)
|
||||
args.each do |arg|
|
||||
self.hidden_actions << arg.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def action_methods
|
||||
@action_names ||= Set.new(super.reject {|name| self.hidden_actions.include?(name.to_s)})
|
||||
|
||||
def action_names
|
||||
action_methods
|
||||
end
|
||||
|
||||
private
|
||||
def action_method?(action_name)
|
||||
!hidden_actions.include?(action_name) && super
|
||||
end
|
||||
|
||||
def self.action_names() action_methods end
|
||||
end
|
||||
module ClassMethods
|
||||
def hide_action(*args)
|
||||
args.each do |arg|
|
||||
self.hidden_actions << arg.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def action_methods
|
||||
@action_names ||= Set.new(super.reject {|name| self.hidden_actions.include?(name.to_s)})
|
||||
end
|
||||
|
||||
def self.action_names
|
||||
action_methods
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'active_support/core_ext/module/delegation'
|
|||
module ActionController
|
||||
class Http < AbstractController::Base
|
||||
abstract!
|
||||
|
||||
|
||||
# :api: public
|
||||
attr_internal :params, :env
|
||||
|
||||
|
@ -14,28 +14,36 @@ module ActionController
|
|||
end
|
||||
|
||||
# :api: public
|
||||
def controller_name() self.class.controller_name end
|
||||
def controller_name
|
||||
self.class.controller_name
|
||||
end
|
||||
|
||||
# :api: public
|
||||
# :api: public
|
||||
def self.controller_path
|
||||
@controller_path ||= self.name.sub(/Controller$/, '').underscore
|
||||
end
|
||||
|
||||
# :api: public
|
||||
def controller_path() self.class.controller_path end
|
||||
|
||||
# :api: private
|
||||
def self.action_names() action_methods end
|
||||
|
||||
|
||||
# :api: public
|
||||
def controller_path
|
||||
self.class.controller_path
|
||||
end
|
||||
|
||||
# :api: private
|
||||
def action_names() action_methods end
|
||||
|
||||
def self.action_names
|
||||
action_methods
|
||||
end
|
||||
|
||||
# :api: private
|
||||
def action_names
|
||||
action_methods
|
||||
end
|
||||
|
||||
# :api: plugin
|
||||
def self.call(env)
|
||||
controller = new
|
||||
controller.call(env).to_rack
|
||||
end
|
||||
|
||||
|
||||
# The details below can be overridden to support a specific
|
||||
# Request and Response object. The default ActionController::Base
|
||||
# implementation includes RackConvenience, which makes a request
|
||||
|
@ -60,14 +68,14 @@ module ActionController
|
|||
def location=(url)
|
||||
headers["Location"] = url
|
||||
end
|
||||
|
||||
|
||||
# :api: private
|
||||
def call(name, env)
|
||||
@_env = env
|
||||
process(name)
|
||||
to_rack
|
||||
end
|
||||
|
||||
|
||||
# :api: private
|
||||
def to_rack
|
||||
[status, headers, response_body]
|
||||
|
|
|
@ -4,33 +4,31 @@ module ActionController
|
|||
|
||||
depends_on ActionController::Renderer
|
||||
depends_on AbstractController::Layouts
|
||||
|
||||
|
||||
module ClassMethods
|
||||
def _implied_layout_name
|
||||
controller_path
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _determine_template(options)
|
||||
super
|
||||
if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout)
|
||||
options[:_layout] = _layout_for_option(options.key?(:layout) ? options[:layout] : :none, options[:_template].details)
|
||||
private
|
||||
def _determine_template(options)
|
||||
super
|
||||
if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout)
|
||||
options[:_layout] = _layout_for_option(options.key?(:layout) ? options[:layout] : :none, options[:_template].details)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def _layout_for_option(name, details)
|
||||
case name
|
||||
when String then _layout_for_name(name, details)
|
||||
when true then _default_layout(true, details)
|
||||
when :none then _default_layout(false, details)
|
||||
when false, nil then nil
|
||||
else
|
||||
raise ArgumentError,
|
||||
"String, true, or false, expected for `layout'; you passed #{name.inspect}"
|
||||
|
||||
def _layout_for_option(name, details)
|
||||
case name
|
||||
when String then _layout_for_name(name, details)
|
||||
when true then _default_layout(true, details)
|
||||
when :none then _default_layout(false, details)
|
||||
when false, nil then nil
|
||||
else
|
||||
raise ArgumentError,
|
||||
"String, true, or false, expected for `layout'; you passed #{name.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,34 +1,33 @@
|
|||
module ActionController
|
||||
module RackConvenience
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
|
||||
included do
|
||||
delegate :headers, :status=, :location=,
|
||||
delegate :headers, :status=, :location=,
|
||||
:status, :location, :content_type, :to => "@_response"
|
||||
attr_internal :request, :response
|
||||
end
|
||||
|
||||
|
||||
def call(name, env)
|
||||
@_request = ActionDispatch::Request.new(env)
|
||||
@_response = ActionDispatch::Response.new
|
||||
@_response.request = request
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
def params
|
||||
@_params ||= @_request.parameters
|
||||
end
|
||||
|
||||
|
||||
# :api: private
|
||||
def to_rack
|
||||
@_response.prepare!
|
||||
@_response.to_a
|
||||
end
|
||||
|
||||
|
||||
def response_body=(body)
|
||||
response.body = body if response
|
||||
super
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module ActionController
|
|||
super(message || DEFAULT_MESSAGE)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module Redirector
|
||||
def redirect_to(url, status) #:doc:
|
||||
raise AbstractController::DoubleRenderError if response_body
|
||||
|
@ -16,4 +16,4 @@ module ActionController
|
|||
self.response_body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
module ActionController
|
||||
module RenderOptions
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor :_renderers
|
||||
self._renderers = []
|
||||
end
|
||||
|
||||
|
||||
module ClassMethods
|
||||
def _write_render_options
|
||||
renderers = _renderers.map do |r|
|
||||
|
@ -17,25 +17,25 @@ module ActionController
|
|||
end
|
||||
RUBY_EVAL
|
||||
end
|
||||
|
||||
|
||||
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
||||
def _handle_render_options(options)
|
||||
#{renderers.join}
|
||||
end
|
||||
RUBY_EVAL
|
||||
end
|
||||
|
||||
|
||||
def _add_render_option(name)
|
||||
_renderers << name
|
||||
_write_render_options
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def render_to_body(options)
|
||||
_handle_render_options(options) || super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module RenderOption
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
|
@ -53,13 +53,13 @@ module ActionController
|
|||
module Json
|
||||
include RenderOption
|
||||
register_renderer :json
|
||||
|
||||
|
||||
def _render_json(json, options)
|
||||
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
|
||||
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
|
||||
self.content_type ||= Mime::JSON
|
||||
self.response_body = json
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Js
|
||||
|
|
|
@ -3,7 +3,7 @@ module ActionController
|
|||
extend ActiveSupport::DependencyModule
|
||||
|
||||
depends_on AbstractController::Renderer
|
||||
|
||||
|
||||
def process_action(*)
|
||||
self.formats = request.formats.map {|x| x.to_sym}
|
||||
super
|
||||
|
@ -21,7 +21,7 @@ module ActionController
|
|||
|
||||
def render_to_body(options)
|
||||
_process_options(options)
|
||||
|
||||
|
||||
if options.key?(:partial)
|
||||
_render_partial(options[:partial], options)
|
||||
end
|
||||
|
@ -29,51 +29,50 @@ module ActionController
|
|||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _prefix
|
||||
controller_path
|
||||
end
|
||||
|
||||
def _determine_template(options)
|
||||
if options.key?(:text)
|
||||
options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first)
|
||||
elsif options.key?(:inline)
|
||||
handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
|
||||
template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
|
||||
options[:_template] = template
|
||||
elsif options.key?(:template)
|
||||
options[:_template_name] = options[:template]
|
||||
elsif options.key?(:file)
|
||||
options[:_template_name] = options[:file]
|
||||
elsif !options.key?(:partial)
|
||||
options[:_template_name] = (options[:action] || action_name).to_s
|
||||
options[:_prefix] = _prefix
|
||||
private
|
||||
def _prefix
|
||||
controller_path
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def _render_partial(partial, options)
|
||||
case partial
|
||||
when true
|
||||
options[:_prefix] = _prefix
|
||||
when String
|
||||
options[:_prefix] = _prefix unless partial.index('/')
|
||||
options[:_template_name] = partial
|
||||
else
|
||||
options[:_partial_object] = true
|
||||
return
|
||||
def _determine_template(options)
|
||||
if options.key?(:text)
|
||||
options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first)
|
||||
elsif options.key?(:inline)
|
||||
handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
|
||||
template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
|
||||
options[:_template] = template
|
||||
elsif options.key?(:template)
|
||||
options[:_template_name] = options[:template]
|
||||
elsif options.key?(:file)
|
||||
options[:_template_name] = options[:file]
|
||||
elsif !options.key?(:partial)
|
||||
options[:_template_name] = (options[:action] || action_name).to_s
|
||||
options[:_prefix] = _prefix
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def _render_partial(partial, options)
|
||||
case partial
|
||||
when true
|
||||
options[:_prefix] = _prefix
|
||||
when String
|
||||
options[:_prefix] = _prefix unless partial.index('/')
|
||||
options[:_template_name] = partial
|
||||
else
|
||||
options[:_partial_object] = true
|
||||
return
|
||||
end
|
||||
|
||||
options[:_partial] = options[:object] || true
|
||||
end
|
||||
|
||||
def _process_options(options)
|
||||
status, content_type, location = options.values_at(:status, :content_type, :location)
|
||||
self.status = status if status
|
||||
self.content_type = content_type if content_type
|
||||
self.headers["Location"] = url_for(location) if location
|
||||
end
|
||||
|
||||
options[:_partial] = options[:object] || true
|
||||
end
|
||||
|
||||
def _process_options(options)
|
||||
status, content_type, location = options.values_at(:status, :content_type, :location)
|
||||
self.status = status if status
|
||||
self.content_type = content_type if content_type
|
||||
self.headers["Location"] = url_for(location) if location
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,22 +32,21 @@ module ActionController #:nodoc:
|
|||
|
||||
attr_internal :rescued_exception
|
||||
|
||||
private
|
||||
private
|
||||
def method_for_action(action_name)
|
||||
return action_name if self.rescued_exception = request.env.delete("action_dispatch.rescue.exception")
|
||||
super
|
||||
end
|
||||
|
||||
def method_for_action(action_name)
|
||||
return action_name if self.rescued_exception = request.env.delete("action_dispatch.rescue.exception")
|
||||
super
|
||||
end
|
||||
def _rescue_action
|
||||
rescue_with_handler(rescued_exception) || raise(rescued_exception)
|
||||
end
|
||||
|
||||
def _rescue_action
|
||||
rescue_with_handler(rescued_exception) || raise(rescued_exception)
|
||||
end
|
||||
|
||||
def process_action(*)
|
||||
super
|
||||
rescue Exception => exception
|
||||
self.rescued_exception = exception
|
||||
_rescue_action
|
||||
end
|
||||
def process_action(*)
|
||||
super
|
||||
rescue Exception => exception
|
||||
self.rescued_exception = exception
|
||||
_rescue_action
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ module ActionController
|
|||
set_test_assigns
|
||||
ret
|
||||
end
|
||||
|
||||
|
||||
def set_test_assigns
|
||||
@assigns = {}
|
||||
(instance_variable_names - self.class.protected_instance_variables).each do |var|
|
||||
|
@ -35,6 +35,5 @@ module ActionController
|
|||
_process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ module ActionController
|
|||
# by this method.
|
||||
def default_url_options(options = nil)
|
||||
end
|
||||
|
||||
|
||||
def rewrite_options(options) #:nodoc:
|
||||
if defaults = default_url_options(options)
|
||||
defaults.merge(options)
|
||||
|
@ -33,7 +33,7 @@ module ActionController
|
|||
options
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def url_for(options = {})
|
||||
options ||= {}
|
||||
case options
|
||||
|
@ -46,4 +46,4 @@ module ActionController
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue