diff options
Diffstat (limited to 'actionpack/lib')
29 files changed, 273 insertions, 261 deletions
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index efc35a7e56..725d8fb8fc 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -15,5 +15,6 @@ module AbstractController autoload :LocalizedCache autoload :Logger autoload :Rendering + autoload :Translation autoload :UrlFor end diff --git a/actionpack/lib/abstract_controller/localized_cache.rb b/actionpack/lib/abstract_controller/localized_cache.rb index bf648af60a..5e3efa002c 100644 --- a/actionpack/lib/abstract_controller/localized_cache.rb +++ b/actionpack/lib/abstract_controller/localized_cache.rb @@ -34,7 +34,7 @@ module AbstractController end end - def render(options) + def render(*args) Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale) super end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index d57136dbb8..a168b1b4c5 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -40,12 +40,13 @@ module AbstractController # Mostly abstracts the fact that calling render twice is a DoubleRenderError. # Delegates render_to_body and sticks the result in self.response_body. - def render(*args) + def render(*args, &block) if response_body - raise AbstractController::DoubleRenderError, "OMG" + raise AbstractController::DoubleRenderError end - self.response_body = render_to_body(*args) + options = _normalize_options(*args, &block) + self.response_body = render_to_body(options) end # Raw rendering of a template to a Rack-compatible body. @@ -69,7 +70,8 @@ module AbstractController # render_to_body into a String. # # :api: plugin - def render_to_string(options = {}) + def render_to_string(*args) + options = _normalize_options(*args) AbstractController::Rendering.body_to_s(render_to_body(options)) end @@ -96,6 +98,11 @@ module AbstractController _view_paths end + # The prefix used in render "foo" shortcuts. + def _prefix + controller_path + end + # Return a string representation of a Rack-compatible response body. def self.body_to_s(body) if body.respond_to?(:to_str) @@ -110,6 +117,28 @@ module AbstractController private + # Normalize options, by converting render "foo" to render :template => "prefix/foo" + # and render "/foo" to render :file => "/foo". + def _normalize_options(action=nil, options={}) + case action + when Hash + options, action = action, nil + when String, Symbol + action = action.to_s + case action.index("/") + when NilClass + options[:_prefix] = _prefix + options[:_template_name] = action + when 0 + options[:file] = action + else + options[:template] = action + end + end + + options + end + # Take in a set of options and determine the template to render # # ==== Options diff --git a/actionpack/lib/action_controller/translation.rb b/actionpack/lib/abstract_controller/translation.rb index 65e9eddb0a..6d68cf4944 100644 --- a/actionpack/lib/action_controller/translation.rb +++ b/actionpack/lib/abstract_controller/translation.rb @@ -1,4 +1,4 @@ -module ActionController +module AbstractController module Translation def translate(*args) I18n.translate(*args) diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 8bc2cc79d2..33e107d216 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -8,7 +8,6 @@ module ActionController autoload :Base autoload :Caching autoload :PolymorphicRoutes - autoload :Translation autoload :Metal autoload :Middleware @@ -17,7 +16,6 @@ module ActionController autoload :ConditionalGet autoload :Configuration autoload :Cookies - autoload :FilterParameterLogging autoload :Flash autoload :Head autoload :Helpers diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 260e5da336..f46231d72b 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -4,6 +4,7 @@ module ActionController include AbstractController::Callbacks include AbstractController::Layouts + include AbstractController::Translation include ActionController::Helpers helper :all # By default, all helpers should be included @@ -32,12 +33,10 @@ module ActionController include ActionController::Streaming include ActionController::HttpAuthentication::Basic::ControllerMethods include ActionController::HttpAuthentication::Digest::ControllerMethods - include ActionController::Translation # Add instrumentations hooks at the bottom, to ensure they instrument # all the methods properly. include ActionController::Instrumentation - include ActionController::FilterParameterLogging # TODO: Extract into its own module # This should be moved together with other normalizing behavior @@ -74,40 +73,13 @@ module ActionController @subclasses ||= [] end - def _normalize_options(action = nil, options = {}, &blk) - if action.is_a?(Hash) - 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 - 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 - - if options[:status] - options[:status] = Rack::Utils.status_code(options[:status]) - end - - options[:update] = blk if block_given? - options - end - - def render(action = nil, options = {}, &blk) - options = _normalize_options(action, options, &blk) - super(options) - end - - def render_to_string(action = nil, options = {}, &blk) - options = _normalize_options(action, options, &blk) - super(options) + # This method has been moved to ActionDispatch::Request.filter_parameters + def self.filter_parameter_logging(*args, &block) + ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller) + filter = Rails.application.config.filter_parameters + filter.concat(args) + filter << block if block + filter end end end diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 1819c0f886..57627a6f0b 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -60,6 +60,7 @@ module ActionController # :api: private def dispatch(name, env) @_env = env + @_env['action_controller.instance'] = self process(name) to_a end diff --git a/actionpack/lib/action_controller/metal/filter_parameter_logging.rb b/actionpack/lib/action_controller/metal/filter_parameter_logging.rb deleted file mode 100644 index 0b1e1ee6ab..0000000000 --- a/actionpack/lib/action_controller/metal/filter_parameter_logging.rb +++ /dev/null @@ -1,71 +0,0 @@ -module ActionController - module FilterParameterLogging - extend ActiveSupport::Concern - - INTERNAL_PARAMS = %w(controller action format _method only_path) - - module ClassMethods - # Replace sensitive parameter data from the request log. - # Filters parameters that have any of the arguments as a substring. - # Looks in all subhashes of the param hash for keys to filter. - # If a block is given, each key and value of the parameter hash and all - # subhashes is passed to it, the value or key - # can be replaced using String#replace or similar method. - # - # Examples: - # - # filter_parameter_logging :password - # => replaces the value to all keys matching /password/i with "[FILTERED]" - # - # filter_parameter_logging :foo, "bar" - # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" - # - # filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i } - # => reverses the value to all keys matching /secret/i - # - # filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i } - # => reverses the value to all keys matching /secret/i, and - # replaces the value to all keys matching /foo|bar/i with "[FILTERED]" - def filter_parameter_logging(*filter_words, &block) - raise "You must filter at least one word from logging" if filter_words.empty? - - parameter_filter = Regexp.new(filter_words.join('|'), true) - - define_method(:filter_parameters) do |original_params| - filtered_params = {} - - original_params.each do |key, value| - if key =~ parameter_filter - value = '[FILTERED]' - elsif value.is_a?(Hash) - value = filter_parameters(value) - elsif value.is_a?(Array) - value = value.map { |item| filter_parameters(item) } - elsif block_given? - key = key.dup - value = value.dup if value.duplicable? - yield key, value - end - - filtered_params[key] = value - end - - filtered_params.except!(*INTERNAL_PARAMS) - end - protected :filter_parameters - end - end - - protected - - def append_info_to_payload(payload) - super - payload[:params] = filter_parameters(request.params) - end - - def filter_parameters(params) - params.dup.except!(*INTERNAL_PARAMS) - end - - end -end diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index d0402e5bad..cdd14560e1 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -100,7 +100,7 @@ module ActionController module_path = module_name.underscore helper module_path rescue MissingSourceFile => e - raise e unless e.is_missing? "#{module_path}_helper" + raise e unless e.is_missing? "helpers/#{module_path}_helper" rescue NameError => e raise e unless e.missing_name? "#{module_name}Helper" end diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 876f778751..7f9a7c068b 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -9,35 +9,34 @@ module ActionController module Instrumentation extend ActiveSupport::Concern - included do - include AbstractController::Logger - end + include AbstractController::Logger attr_internal :view_runtime def process_action(action, *args) - ActiveSupport::Notifications.instrument("action_controller.process_action") do |payload| + raw_payload = { + :controller => self.class.name, + :action => self.action_name, + :params => request.filtered_parameters, + :formats => request.formats.map(&:to_sym) + } + + ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup) + + ActiveSupport::Notifications.instrument("action_controller.process_action", raw_payload) do |payload| result = super - payload[:controller] = self.class.name - payload[:action] = self.action_name - payload[:status] = response.status + payload[:status] = response.status append_info_to_payload(payload) result end end - def render(*args, &block) - if logger - render_output = nil - - self.view_runtime = cleanup_view_runtime do - Benchmark.ms { render_output = super } - end - - render_output - else - super + def render(*args) + render_output = nil + self.view_runtime = cleanup_view_runtime do + Benchmark.ms { render_output = super } end + render_output end def send_file(path, options={}) diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 74e50bb032..72e2bbd00e 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -12,9 +12,10 @@ module ActionController super end - def render(options) - super - self.content_type ||= options[:_template].mime_type.to_s + def render(*args) + args << {} unless args.last.is_a?(Hash) + super(*args) + self.content_type ||= args.last[:_template].mime_type.to_s response_body end @@ -24,18 +25,6 @@ module ActionController end private - def _prefix - controller_path - end - - def _determine_template(options) - if (options.keys & [:partial, :file, :template, :text, :inline]).empty? - options[:_template_name] ||= options[:action] - options[:_prefix] = _prefix - end - - super - end def _render_partial(options) options[:partial] = action_name if options[:partial] == true @@ -53,5 +42,29 @@ module ActionController self.content_type = content_type if content_type self.headers["Location"] = url_for(location) if location end + + def _normalize_options(action=nil, options={}, &blk) + case action + when NilClass + when Hash + options = super(action.delete(:action), action) + when String, Symbol + options = super + else + options.merge! :partial => action + end + + if (options.keys & [:partial, :file, :template, :text, :inline]).empty? + options[:_template_name] ||= options[:action] + options[:_prefix] = _prefix + end + + if options[:status] + options[:status] = Rack::Utils.status_code(options[:status]) + end + + options[:update] = blk if block_given? + options + end end end diff --git a/actionpack/lib/action_controller/railties/subscriber.rb b/actionpack/lib/action_controller/railties/subscriber.rb index 6659e5df47..1f0e6bf51a 100644 --- a/actionpack/lib/action_controller/railties/subscriber.rb +++ b/actionpack/lib/action_controller/railties/subscriber.rb @@ -1,15 +1,23 @@ module ActionController module Railties class Subscriber < Rails::Subscriber - def process_action(event) + INTERNAL_PARAMS = %w(controller action format _method only_path) + + def start_processing(event) payload = event.payload - info " Parameters: #{payload[:params].inspect}" unless payload[:params].blank? + params = payload[:params].except(*INTERNAL_PARAMS) + info " Processing by #{payload[:controller]}##{payload[:action]} as #{payload[:formats].first.to_s.upcase}" + info " Parameters: #{params.inspect}" unless params.empty? + end + + def process_action(event) + payload = event.payload additions = ActionController::Base.log_process_action(payload) message = "Completed in %.0fms" % event.duration message << " (#{additions.join(" | ")})" unless additions.blank? - message << " by #{payload[:controller]}##{payload[:action]} [#{payload[:status]}]" + message << " with #{payload[:status]}" info(message) end diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 082562d921..f0490a5619 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -46,7 +46,6 @@ module ActionDispatch autoload :Cookies autoload :Flash autoload :Head - autoload :Notifications autoload :ParamsParser autoload :Rescue autoload :ShowExceptions @@ -63,6 +62,7 @@ module ActionDispatch autoload :Headers autoload :MimeNegotiation autoload :Parameters + autoload :FilterParameters autoload :Upload autoload :UploadedFile, 'action_dispatch/http/upload' autoload :URL diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb new file mode 100644 index 0000000000..1958e1668d --- /dev/null +++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb @@ -0,0 +1,98 @@ +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/hash/keys' + +module ActionDispatch + module Http + # Allows you to specify sensitive parameters which will be replaced from + # the request log by looking in all subhashes of the param hash for keys + # to filter. If a block is given, each key and value of the parameter + # hash and all subhashes is passed to it, the value or key can be replaced + # using String#replace or similar method. + # + # Examples: + # + # env["action_dispatch.parameter_filter"] = [:password] + # => replaces the value to all keys matching /password/i with "[FILTERED]" + # + # env["action_dispatch.parameter_filter"] = [:foo, "bar"] + # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" + # + # env["action_dispatch.parameter_filter"] = lambda do |k,v| + # v.reverse! if k =~ /secret/i + # end + # => reverses the value to all keys matching /secret/i + # + module FilterParameters + extend ActiveSupport::Concern + + # Return a hash of parameters with all sensitive data replaced. + def filtered_parameters + @filtered_parameters ||= process_parameter_filter(parameters) + end + alias :fitered_params :filtered_parameters + + # Return a hash of request.env with all sensitive data replaced. + def filtered_env + filtered_env = @env.dup + filtered_env.each do |key, value| + if (key =~ /RAW_POST_DATA/i) + filtered_env[key] = '[FILTERED]' + elsif value.is_a?(Hash) + filtered_env[key] = process_parameter_filter(value) + end + end + filtered_env + end + + protected + + def compile_parameter_filter #:nodoc: + strings, regexps, blocks = [], [], [] + + Array(@env["action_dispatch.parameter_filter"]).each do |item| + case item + when NilClass + when Proc + blocks << item + when Regexp + regexps << item + else + strings << item.to_s + end + end + + regexps << Regexp.new(strings.join('|'), true) unless strings.empty? + [regexps, blocks] + end + + def filtering_parameters? #:nodoc: + @env["action_dispatch.parameter_filter"].present? + end + + def process_parameter_filter(original_params) #:nodoc: + return original_params.dup unless filtering_parameters? + + filtered_params = {} + regexps, blocks = compile_parameter_filter + + original_params.each do |key, value| + if regexps.find { |r| key =~ r } + value = '[FILTERED]' + elsif value.is_a?(Hash) + value = process_parameter_filter(value) + elsif value.is_a?(Array) + value = value.map { |i| process_parameter_filter(i) } + elsif blocks.present? + key = key.dup + value = value.dup if value.duplicable? + blocks.each { |b| b.call(key, value) } + end + + filtered_params[key] = value + end + + filtered_params + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index 97546d5f93..40b40ea94e 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -29,9 +29,8 @@ module ActionDispatch def path_parameters @env["action_dispatch.request.path_parameters"] ||= {} end - - private + private # Convert nested Hashs to HashWithIndifferentAccess def normalize_parameters(value) case value diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 187ce7c15d..7a17023ed2 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -11,6 +11,7 @@ module ActionDispatch include ActionDispatch::Http::Cache::Request include ActionDispatch::Http::MimeNegotiation include ActionDispatch::Http::Parameters + include ActionDispatch::Http::FilterParameters include ActionDispatch::Http::Upload include ActionDispatch::Http::URL diff --git a/actionpack/lib/action_dispatch/middleware/notifications.rb b/actionpack/lib/action_dispatch/middleware/notifications.rb deleted file mode 100644 index 01d2cbb435..0000000000 --- a/actionpack/lib/action_dispatch/middleware/notifications.rb +++ /dev/null @@ -1,24 +0,0 @@ -module ActionDispatch - # Provide notifications in the middleware stack. Notice that for the before_dispatch - # and after_dispatch notifications, we just send the original env, so we don't pile - # up large env hashes in the queue. However, in exception cases, the whole env hash - # is actually useful, so we send it all. - class Notifications - def initialize(app) - @app = app - end - - def call(stack_env) - env = stack_env.dup - ActiveSupport::Notifications.instrument("action_dispatch.before_dispatch", :env => env) - - ActiveSupport::Notifications.instrument!("action_dispatch.after_dispatch", :env => env) do - @app.call(stack_env) - end - rescue Exception => exception - ActiveSupport::Notifications.instrument('action_dispatch.exception', - :env => stack_env, :exception => exception) - raise exception - end - end -end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 534390d4aa..522982e202 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -35,14 +35,14 @@ module ActionDispatch when Proc strategy.call(request.raw_post) when :xml_simple, :xml_node - request.body.size == 0 ? {} : Hash.from_xml(request.body).with_indifferent_access + request.body.size == 0 ? {} : Hash.from_xml(request.raw_post).with_indifferent_access when :yaml - YAML.load(request.body) + YAML.load(request.raw_post) when :json if request.body.size == 0 {} else - data = ActiveSupport::JSON.decode(request.body) + data = ActiveSupport::JSON.decode(request.raw_post) data = {:_json => data} unless data.is_a?(Hash) data.with_indifferent_access end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 24be4fee55..0dc1d70e37 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -60,9 +60,7 @@ module ActionDispatch end def inspect - str = klass.to_s - args.each { |arg| str += ", #{build_args.inspect}" } - str + klass.to_s end def build(app) diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 18978bfb39..e4bd143e78 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -5,9 +5,6 @@ module ActionDispatch class Railtie < Rails::Railtie plugin_name :action_dispatch - require "action_dispatch/railties/subscriber" - subscriber ActionDispatch::Railties::Subscriber.new - # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| # TODO: This used to say unless defined?(Dispatcher). Find out why and fix. diff --git a/actionpack/lib/action_dispatch/railties/subscriber.rb b/actionpack/lib/action_dispatch/railties/subscriber.rb deleted file mode 100644 index c08a844c6a..0000000000 --- a/actionpack/lib/action_dispatch/railties/subscriber.rb +++ /dev/null @@ -1,17 +0,0 @@ -module ActionDispatch - module Railties - class Subscriber < Rails::Subscriber - def before_dispatch(event) - request = Request.new(event.payload[:env]) - path = request.request_uri.inspect rescue "unknown" - - info "\n\nProcessing #{path} to #{request.formats.join(', ')} " << - "(for #{request.remote_ip} at #{event.time.to_s(:db)}) [#{request.method.to_s.upcase}]" - end - - def logger - ActionController::Base.logger - end - end - end -end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 811c287355..fcbb70749f 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -375,6 +375,15 @@ module ActionDispatch end end + def action_type(action) + case action + when :index, :create + :collection + when :show, :update, :destroy + :member + end + end + def name options[:as] || plural end @@ -391,6 +400,15 @@ module ActionDispatch plural end + def name_for_action(action) + case action_type(action) + when :collection + collection_name + when :member + member_name + end + end + def id_segment ":#{singular}_id" end @@ -405,6 +423,13 @@ module ActionDispatch super end + def action_type(action) + case action + when :show, :create, :update, :destroy + :member + end + end + def name options[:as] || singular end @@ -428,7 +453,7 @@ module ActionDispatch with_scope_level(:resource, resource) do yield if block_given? - get :show, :as => resource.member_name if resource.actions.include?(:show) + get :show if resource.actions.include?(:show) post :create if resource.actions.include?(:create) put :update if resource.actions.include?(:update) delete :destroy if resource.actions.include?(:destroy) @@ -454,14 +479,14 @@ module ActionDispatch yield if block_given? with_scope_level(:collection) do - get :index, :as => resource.collection_name if resource.actions.include?(:index) + get :index if resource.actions.include?(:index) post :create if resource.actions.include?(:create) get :new, :as => resource.singular if resource.actions.include?(:new) end with_scope_level(:member) do scope(':id') do - get :show, :as => resource.member_name if resource.actions.include?(:show) + get :show if resource.actions.include?(:show) put :update if resource.actions.include?(:update) delete :destroy if resource.actions.include?(:destroy) get :edit, :as => resource.singular if resource.actions.include?(:edit) @@ -525,7 +550,10 @@ module ActionDispatch begin old_path = @scope[:path] @scope[:path] = "#{@scope[:path]}(.:format)" - return match(options.reverse_merge(:to => action)) + return match(options.reverse_merge( + :to => action, + :as => parent_resource.name_for_action(action) + )) ensure @scope[:path] = old_path end diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb index f1431e7a37..e6e44d3546 100644 --- a/actionpack/lib/action_dispatch/routing/route.rb +++ b/actionpack/lib/action_dispatch/routing/route.rb @@ -44,6 +44,12 @@ module ActionDispatch def to_a [@app, @conditions, @defaults, @name] end + + def to_s + @to_s ||= begin + "%-6s %-40s %s" % [(verb || :any).to_s.upcase, path, requirements.inspect] + end + end end end end diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 4ec47d146c..2093bb3a0e 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -240,9 +240,9 @@ module ActionDispatch path = location.query ? "#{location.path}?#{location.query}" : location.path end - [ControllerCapture, ActionController::Testing].each do |mod| - unless ActionController::Base < mod - ActionController::Base.class_eval { include mod } + unless ActionController::Base < ActionController::Testing + ActionController::Base.class_eval do + include ActionController::Testing end end @@ -259,7 +259,9 @@ module ActionDispatch "HTTP_HOST" => host, "REMOTE_ADDR" => remote_addr, "CONTENT_TYPE" => "application/x-www-form-urlencoded", - "HTTP_ACCEPT" => accept + "HTTP_ACCEPT" => accept, + + "action_dispatch.show_exceptions" => false } (rack_environment || {}).each do |key, value| @@ -267,16 +269,15 @@ module ActionDispatch end session = Rack::Test::Session.new(@mock_session) - - @controller = ActionController::Base.capture_instantiation do - session.request(path, env) - end + session.request(path, env) @request_count += 1 @request = ActionDispatch::Request.new(session.last_request.env) @response = ActionDispatch::TestResponse.from_response(@mock_session.last_response) @html_document = nil + @controller = session.last_request.env['action_controller.instance'] + return response.status end @@ -294,31 +295,6 @@ module ActionDispatch end end - # A module used to extend ActionController::Base, so that integration tests - # can capture the controller used to satisfy a request. - module ControllerCapture #:nodoc: - extend ActiveSupport::Concern - - included do - alias_method_chain :initialize, :capture - end - - def initialize_with_capture(*args) - initialize_without_capture - self.class.last_instantiation ||= self - end - - module ClassMethods #:nodoc: - mattr_accessor :last_instantiation - - def capture_instantiation - self.last_instantiation = nil - yield - return last_instantiation - end - end - end - module Runner def app @app diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 4970c768e8..c4b0455c2a 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -181,7 +181,6 @@ module ActionView #:nodoc: extend ActiveSupport::Memoizable attr_accessor :base_path, :assigns, :template_extension, :formats - attr_accessor :controller attr_internal :captures def reset_formats(formats) @@ -277,13 +276,13 @@ module ActionView #:nodoc: @config = nil @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } - @controller = controller + @_controller = controller @helpers = self.class.helpers || Module.new @_content_for = Hash.new {|h,k| h[k] = ActionView::SafeBuffer.new } self.view_paths = view_paths end - attr_internal :template + attr_internal :controller, :template attr_reader :view_paths def view_paths=(paths) @@ -298,12 +297,11 @@ module ActionView #:nodoc: # Evaluates the local assigns and controller ivars, pushes them to the view. def _evaluate_assigns_and_ivars #:nodoc: - if @controller - variables = @controller.instance_variable_names - variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables) - variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) } + if controller + variables = controller.instance_variable_names + variables -= controller.protected_instance_variables if controller.respond_to?(:protected_instance_variables) + variables.each { |name| instance_variable_set(name, controller.instance_variable_get(name)) } end end - end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 15b70ecff5..83357dd76f 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -634,8 +634,8 @@ module ActionView # Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL # roots. Rewrite the asset path for cache-busting asset ids. Include # asset host, if configured, with the correct request protocol. - def compute_public_path(source, dir, ext = nil, include_host = true) - has_request = @controller.respond_to?(:request) + def compute_public_path(source, dir, ext = nil, include_host = true) + has_request = controller.respond_to?(:request) source_ext = File.extname(source)[1..-1] if ext && !is_uri?(source) && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}")))) @@ -658,7 +658,7 @@ module ActionView host = compute_asset_host(source) if has_request && !host.blank? && !is_uri?(host) - host = "#{@controller.request.protocol}#{host}" + host = "#{controller.request.protocol}#{host}" end "#{host}#{source}" @@ -681,7 +681,7 @@ module ActionView if host.is_a?(Proc) || host.respond_to?(:call) case host.is_a?(Proc) ? host.arity : host.method(:call).arity when 2 - request = @controller.respond_to?(:request) && @controller.request + request = controller.respond_to?(:request) && controller.request host.call(source, request) else host.call(source) diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb index 64d1ad2715..d5cc14b29a 100644 --- a/actionpack/lib/action_view/helpers/cache_helper.rb +++ b/actionpack/lib/action_view/helpers/cache_helper.rb @@ -32,7 +32,7 @@ module ActionView # <i>Topics listed alphabetically</i> # <% end %> def cache(name = {}, options = nil, &block) - @controller.fragment_for(output_buffer, name, options, &block) + controller.fragment_for(output_buffer, name, options, &block) end end end diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 14628c5404..511386fede 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -13,7 +13,7 @@ module ActionView # Need to map default url options to controller one. def default_url_options(*args) #:nodoc: - @controller.send(:default_url_options, *args) + controller.send(:default_url_options, *args) end # Returns the URL for the set of +options+ provided. This takes the @@ -89,10 +89,10 @@ module ActionView when Hash options = { :only_path => options[:host].nil? }.update(options.symbolize_keys) escape = options.key?(:escape) ? options.delete(:escape) : false - @controller.send(:url_for, options) + controller.send(:url_for, options) when :back escape = false - @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()' + controller.request.env["HTTP_REFERER"] || 'javascript:history.back()' else escape = false polymorphic_path(options) @@ -546,10 +546,10 @@ module ActionView # # => false def current_page?(options) url_string = CGI.unescapeHTML(url_for(options)) - request = @controller.request - # We ignore any extra parameters in the request_uri if the + request = controller.request + # We ignore any extra parameters in the request_uri if the # submitted url doesn't have any either. This lets the function - # work with things like ?order=asc + # work with things like ?order=asc if url_string.index("?") request_uri = request.request_uri else diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index ec278ca783..7c33f1334a 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/try' + module ActionView module Rendering # Returns the result of a render that's dictated by the options hash. The primary options are: |