diff options
Diffstat (limited to 'actionpack/lib/action_controller')
14 files changed, 116 insertions, 83 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 8611d0d3c3..a70ba0d2e3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -1,3 +1,5 @@ +require "action_controller/log_subscriber" + module ActionController class Base < Metal abstract! diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb new file mode 100644 index 0000000000..ece270b3ce --- /dev/null +++ b/actionpack/lib/action_controller/log_subscriber.rb @@ -0,0 +1,56 @@ +require 'active_support/core_ext/object/blank' + +module ActionController + class LogSubscriber < ActiveSupport::LogSubscriber + INTERNAL_PARAMS = %w(controller action format _method only_path) + + def start_processing(event) + payload = event.payload + 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 #{payload[:status]} #{Rack::Utils::HTTP_STATUS_CODES[payload[:status]]} in %.0fms" % event.duration + message << " (#{additions.join(" | ")})" unless additions.blank? + + info(message) + end + + def send_file(event) + message = "Sent file %s" + message << " (%.1fms)" + info(message % [event.payload[:path], event.duration]) + end + + def redirect_to(event) + info "Redirected to #{event.payload[:location]}" + end + + def send_data(event) + info("Sent data %s (%.1fms)" % [event.payload[:filename], event.duration]) + end + + %w(write_fragment read_fragment exist_fragment? + expire_fragment expire_page write_page).each do |method| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(event) + key_or_path = event.payload[:key] || event.payload[:path] + human_name = #{method.to_s.humanize.inspect} + info("\#{human_name} \#{key_or_path} (%.1fms)" % event.duration) + end + METHOD + end + + def logger + ActionController::Base.logger + end + end +end + +ActionController::LogSubscriber.attach_to :action_controller
\ No newline at end of file diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 775a5002e2..2281c500c5 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -52,8 +52,7 @@ module ActionController class Metal < AbstractController::Base abstract! - # :api: public - attr_internal :params, :env + attr_internal :env # Returns the last part of the controller's name, underscored, without the ending # "Controller". For instance, MyApp::MyPostsController would return "my_posts" for @@ -62,7 +61,7 @@ module ActionController # ==== Returns # String def self.controller_name - @controller_name ||= controller_path.split("/").last + @controller_name ||= self.name.demodulize.sub(/Controller$/, '').underscore end # Delegates to the class' #controller_name @@ -85,6 +84,14 @@ module ActionController super end + def params + @_params ||= request.parameters + end + + def params=(val) + @_params = val + end + # Basic implementations for content_type=, location=, and headers are # provided to reduce the dependency on the RackDelegation module # in Renderer and Redirector. diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index b6d4fb1284..89201fb5ee 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -58,12 +58,12 @@ module ActionController module ClassMethods def helpers_dir - ActiveSupport::Deprecation.warn "helpers_dir is deprecated, use helpers_path instead" + ActiveSupport::Deprecation.warn "helpers_dir is deprecated, use helpers_path instead", caller self.helpers_path end def helpers_dir=(value) - ActiveSupport::Deprecation.warn "helpers_dir= is deprecated, use helpers_path= instead" + ActiveSupport::Deprecation.warn "helpers_dir= is deprecated, use helpers_path= instead", caller self.helpers_path = Array(value) end diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index 508ea6e2b7..544b4989c7 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -14,10 +14,6 @@ module ActionController super(action, request) end - def params - @_params ||= @_request.parameters - end - def response_body=(body) response.body = body if response super diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 8c25b147ef..b632e7aab6 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -55,7 +55,7 @@ module ActionController #:nodoc: config_accessor :request_forgery_protection_token self.request_forgery_protection_token ||= :authenticity_token - # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. + # Controls whether request forgery protection is turned on or not. Turned off by default only in test mode. config_accessor :allow_forgery_protection self.allow_forgery_protection = true if allow_forgery_protection.nil? diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb index 22bdcd0f3c..cb644dfd16 100644 --- a/actionpack/lib/action_controller/metal/responder.rb +++ b/actionpack/lib/action_controller/metal/responder.rb @@ -89,9 +89,7 @@ module ActionController #:nodoc: def initialize(controller, resources, options={}) @controller = controller - @request = controller.request - @format = controller.formats.first - @resource = resources.is_a?(Array) ? resources.last : resources + @resource = resources.last @resources = resources @options = options @action = options.delete(:action) @@ -101,6 +99,14 @@ module ActionController #:nodoc: delegate :head, :render, :redirect_to, :to => :controller delegate :get?, :post?, :put?, :delete?, :to => :request + def request + @request ||= @controller.request + end + + def format + @format ||= @controller.formats.first + end + # Undefine :to_json and :to_yaml since it's defined on Object undef_method(:to_json) if method_defined?(:to_json) undef_method(:to_yaml) if method_defined?(:to_yaml) @@ -147,7 +153,7 @@ module ActionController #:nodoc: elsif has_errors? && default_action render :action => default_action else - redirect_to resource_location + redirect_to navigation_location end end @@ -160,7 +166,7 @@ module ActionController #:nodoc: elsif has_errors? display resource.errors, :status => :unprocessable_entity elsif post? - display resource, :status => :created, :location => resource_location + display resource, :status => :created, :location => api_location else head :ok end @@ -178,6 +184,8 @@ module ActionController #:nodoc: def resource_location options[:location] || resources end + alias :navigation_location :resource_location + alias :api_location :resource_location # If a given response block was given, use it, otherwise call render on # controller. diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index 7f2eb4306b..bee50a7a3b 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -11,7 +11,7 @@ module ActionController # polymorphic_url([:admin, @article, @comment]) # # results in: - # + # # admin_article_comment_url(@article, @comment) # # == Usage within the framework @@ -166,6 +166,7 @@ module ActionController route << RecordIdentifier.__send__("plural_class_name", record) route = route.singularize if inflection == :singular route << "_" + route << "index_" if RecordIdentifier.uncountable?(record) && inflection == :plural end action_prefix(options) + route + routing_type(options).to_s diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 0e3cdffadc..86395c4d93 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -6,7 +6,6 @@ require "active_support/core_ext/class/subclasses" require "active_support/deprecation/proxy_wrappers" require "active_support/deprecation" -require "action_controller/railties/log_subscriber" require "action_controller/railties/url_helpers" module ActionController @@ -35,8 +34,6 @@ module ActionController end end - log_subscriber :action_controller, ActionController::Railties::LogSubscriber.new - initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller diff --git a/actionpack/lib/action_controller/railties/log_subscriber.rb b/actionpack/lib/action_controller/railties/log_subscriber.rb deleted file mode 100644 index 00ac3bdf67..0000000000 --- a/actionpack/lib/action_controller/railties/log_subscriber.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'active_support/core_ext/object/blank' - -module ActionController - module Railties - class LogSubscriber < Rails::LogSubscriber - INTERNAL_PARAMS = %w(controller action format _method only_path) - - def start_processing(event) - payload = event.payload - 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 #{payload[:status]} #{Rack::Utils::HTTP_STATUS_CODES[payload[:status]]} in %.0fms" % event.duration - message << " (#{additions.join(" | ")})" unless additions.blank? - - info(message) - end - - def send_file(event) - message = "Sent file %s" - message << " (%.1fms)" - info(message % [event.payload[:path], event.duration]) - end - - def redirect_to(event) - info "Redirected to #{event.payload[:location]}" - end - - def send_data(event) - info("Sent data %s (%.1fms)" % [event.payload[:filename], event.duration]) - end - - %w(write_fragment read_fragment exist_fragment? - expire_fragment expire_page write_page).each do |method| - class_eval <<-METHOD, __FILE__, __LINE__ + 1 - def #{method}(event) - key_or_path = event.payload[:key] || event.payload[:path] - human_name = #{method.to_s.humanize.inspect} - info("\#{human_name} \#{key_or_path} (%.1fms)" % event.duration) - end - METHOD - end - - def logger - ActionController::Base.logger - end - end - end -end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 907c369218..d20c3b64c5 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -1,7 +1,7 @@ require 'active_support/core_ext/module' module ActionController - # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or + # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or # Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate # the view actions to a higher logical level. Example: # @@ -28,7 +28,7 @@ module ActionController # end # # As the example above shows, you can stop caring to a large extent what the actual id of the post is. You just know - # that one is being assigned and that the subsequent calls in redirect_to and the RJS expect that same naming + # that one is being assigned and that the subsequent calls in redirect_to and the RJS expect that same naming # convention and allows you to write less code if you follow it. module RecordIdentifier extend self @@ -59,7 +59,7 @@ module ActionController # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id: # # dom_id(Post.find(45), :edit) # => "edit_post_45" - def dom_id(record, prefix = nil) + def dom_id(record, prefix = nil) if record_id = record_key_for_dom_id(record) "#{dom_class(record, prefix)}#{JOIN}#{record_id}" else @@ -102,6 +102,14 @@ module ActionController model_name_from_record_or_class(record_or_class).singular end + # Identifies whether the class name of a record or class is uncountable. Examples: + # + # uncountable?(Sheep) # => true + # uncountable?(Post) => false + def uncountable?(record_or_class) + plural_class_name(record_or_class) == singular_class_name(record_or_class) + end + private def model_name_from_record_or_class(record_or_class) (record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 21281b606e..650eb16ac0 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -40,7 +40,7 @@ module ActionController ActiveSupport::Notifications.unsubscribe("!render_template.action_view") end - # Asserts that the request was rendered with the appropriate template file or partials + # Asserts that the request was rendered with the appropriate template file or partials. # # ==== Examples # @@ -53,6 +53,12 @@ module ActionController # # assert that no partials were rendered # assert_template :partial => false # + # In a view test case, you can also assert that specific locals are passed + # to partials: + # + # # assert that the "_customer" partial was rendered with a specific object + # assert_template :partial => '_customer', :locals => { :customer => @customer } + # def assert_template(options = {}, message = nil) validate_request! @@ -72,9 +78,13 @@ module ActionController end when Hash if expected_partial = options[:partial] - if expected_count = options[:count] + if expected_locals = options[:locals] + actual_locals = @locals[expected_partial.to_s.sub(/^_/,'')] + expected_locals.each_pair do |k,v| + assert_equal(v, actual_locals[k]) + end + elsif expected_count = options[:count] actual_count = @partials[expected_partial] - # actual_count = found.nil? ? 0 : found[1] msg = build_message(message, "expecting ? to be rendered ? time(s) but rendered ? time(s)", expected_partial, expected_count, actual_count) @@ -183,12 +193,14 @@ module ActionController replace(session.stringify_keys) @loaded = true end + + def exists?; true; end end # Superclass for ActionController functional tests. Functional tests allow you to # test a single controller action per test method. This should not be confused with # integration tests (see ActionController::IntegrationTest), which are more like - # "stories" that can involve multiple controllers and mutliple actions (i.e. multiple + # "stories" that can involve multiple controllers and multiple actions (i.e. multiple # different HTTP requests). # # == Basic example @@ -442,7 +454,7 @@ module ActionController end # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline - # (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular + # (skipping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else # than 0.0.0.0. # diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb index 6c0331636c..a874519978 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb @@ -177,6 +177,7 @@ module HTML #:nodoc: case text when "\\" then value << text + break if scanner.eos? value << scanner.getch when delim break diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb index 064ff3724d..240dc1890f 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb @@ -96,6 +96,7 @@ module HTML #:nodoc: while match = @scanner.scan_until(/[\\#{delim}]/) text << match break if @scanner.matched == delim + break if @scanner.eos? text << @scanner.getch # skip the escaped character end end |