Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' into nested_has_many_through_2

  • Loading branch information...
commit 704961ce688f5bc1942529f44ea6b00014ef8378 2 parents b689834 + 91deff0
@jonleighton jonleighton authored
Showing with 1,536 additions and 849 deletions.
  1. +3 −6 actionmailer/lib/action_mailer/base.rb
  2. +10 −0 actionmailer/lib/action_mailer/railtie.rb
  3. +1 −1  actionpack/Rakefile
  4. +4 −4 actionpack/lib/abstract_controller/base.rb
  5. +1 −2  actionpack/lib/abstract_controller/layouts.rb
  6. +0 −1  actionpack/lib/abstract_controller/url_for.rb
  7. +1 −0  actionpack/lib/action_controller.rb
  8. +1 −1  actionpack/lib/action_controller/caching/actions.rb
  9. +1 −2  actionpack/lib/action_controller/caching/pages.rb
  10. +4 −1 actionpack/lib/action_controller/metal.rb
  11. +3 −3 actionpack/lib/action_controller/metal/helpers.rb
  12. +10 −12 actionpack/lib/action_controller/metal/http_authentication.rb
  13. +1 −1  actionpack/lib/action_controller/metal/renderers.rb
  14. +11 −7 actionpack/lib/action_controller/metal/url_for.rb
  15. +10 −0 actionpack/lib/action_controller/railtie.rb
  16. +8 −6 actionpack/lib/action_controller/test_case.rb
  17. +4 −4 actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
  18. +9 −10 actionpack/lib/action_dispatch/http/request.rb
  19. +0 −1  actionpack/lib/action_dispatch/http/response.rb
  20. +2 −2 actionpack/lib/action_dispatch/http/url.rb
  21. +5 −3 actionpack/lib/action_dispatch/middleware/callbacks.rb
  22. +3 −3 actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
  23. +6 −3 actionpack/lib/action_dispatch/middleware/stack.rb
  24. +1 −1  actionpack/lib/action_dispatch/middleware/static.rb
  25. +2 −2 actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
  26. +3 −3 actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
  27. +26 −22 actionpack/lib/action_dispatch/routing/mapper.rb
  28. +5 −5 actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
  29. +24 −22 actionpack/lib/action_dispatch/routing/route_set.rb
  30. +5 −0 actionpack/lib/action_dispatch/routing/url_for.rb
  31. +2 −6 actionpack/lib/action_dispatch/testing/assertions/response.rb
  32. +12 −12 actionpack/lib/action_dispatch/testing/assertions/routing.rb
  33. +5 −3 actionpack/lib/action_dispatch/testing/assertions/selector.rb
  34. +20 −13 actionpack/lib/action_dispatch/testing/integration.rb
  35. +2 −1  actionpack/lib/action_dispatch/testing/test_request.rb
  36. +1 −2  actionpack/lib/action_view/base.rb
  37. +19 −11 actionpack/lib/action_view/helpers/asset_tag_helper.rb
  38. +1 −0  actionpack/lib/action_view/helpers/date_helper.rb
  39. +22 −15 actionpack/lib/action_view/helpers/form_helper.rb
  40. +5 −6 actionpack/lib/action_view/helpers/form_options_helper.rb
  41. +1 −1  actionpack/lib/action_view/helpers/text_helper.rb
  42. +15 −13 actionpack/lib/action_view/helpers/url_helper.rb
  43. +2 −0  actionpack/lib/action_view/template.rb
  44. +1 −0  actionpack/lib/action_view/template/error.rb
  45. +1 −0  actionpack/lib/action_view/template/resolver.rb
  46. +16 −13 actionpack/lib/action_view/test_case.rb
  47. +4 −4 actionpack/lib/action_view/testing/resolvers.rb
  48. +4 −2 actionpack/test/abstract/callbacks_test.rb
  49. +1 −1  actionpack/test/abstract/layouts_test.rb
  50. +2 −2 actionpack/test/activerecord/controller_runtime_test.rb
  51. +0 −32 actionpack/test/activerecord/render_partial_with_record_identification_test.rb
  52. +10 −3 actionpack/test/controller/action_pack_assertions_test.rb
  53. +4 −3 actionpack/test/controller/caching_test.rb
  54. +9 −1 actionpack/test/controller/capture_test.rb
  55. +2 −1  actionpack/test/controller/filters_test.rb
  56. +14 −14 actionpack/test/controller/log_subscriber_test.rb
  57. +2 −2 actionpack/test/controller/mime_responds_test.rb
  58. +13 −0 actionpack/test/controller/render_json_test.rb
  59. +4 −3 actionpack/test/controller/render_other_test.rb
  60. +8 −1 actionpack/test/controller/render_test.rb
  61. +18 −19 actionpack/test/controller/request_forgery_protection_test.rb
  62. +2 −0  actionpack/test/controller/rescue_test.rb
  63. +1 −1  actionpack/test/controller/selector_test.rb
  64. +1 −1  actionpack/test/controller/test_test.rb
  65. +1 −1  actionpack/test/controller/url_for_test.rb
  66. +1 −0  actionpack/test/controller/webservice_test.rb
  67. +5 −5 actionpack/test/dispatch/cookies_test.rb
  68. +0 −1  actionpack/test/dispatch/mime_type_test.rb
  69. +77 −16 actionpack/test/dispatch/prefix_generation_test.rb
  70. +1 −1  actionpack/test/dispatch/request/multipart_params_parsing_test.rb
  71. +1 −0  actionpack/test/dispatch/request/xml_params_parsing_test.rb
  72. +4 −3 actionpack/test/dispatch/request_test.rb
  73. +8 −8 actionpack/test/dispatch/response_test.rb
  74. +18 −8 actionpack/test/dispatch/routing_test.rb
  75. +1 −1  actionpack/test/dispatch/session/cookie_store_test.rb
  76. +7 −7 actionpack/test/dispatch/show_exceptions_test.rb
  77. +1 −1  actionpack/test/fixtures/alternate_helpers/foo_helper.rb
  78. +0 −1  actionpack/test/fixtures/test/hello_world_from_rxml.builder
  79. +1 −1  actionpack/test/fixtures/test/proper_block_detection.erb
  80. +1 −1  actionpack/test/template/asset_tag_helper_test.rb
  81. +1 −1  actionpack/test/template/atom_feed_helper_test.rb
  82. +0 −20 actionpack/test/template/date_helper_test.rb
  83. +1 −2  actionpack/test/template/form_helper_test.rb
  84. +2 −2 actionpack/test/template/html-scanner/tag_node_test.rb
  85. +0 −2  actionpack/test/template/javascript_helper_test.rb
  86. +9 −9 actionpack/test/template/log_subscriber_test.rb
  87. +5 −5 actionpack/test/template/number_helper_i18n_test.rb
  88. +1 −1  actionpack/test/template/prototype_helper_test.rb
  89. +3 −2 actionpack/test/template/render_test.rb
  90. +3 −3 actionpack/test/template/tag_helper_test.rb
  91. +9 −8 actionpack/test/template/template_test.rb
  92. +3 −3 actionpack/test/template/test_case_test.rb
  93. +1 −1  actionpack/test/template/text_helper_test.rb
  94. +4 −2 activemodel/lib/active_model/naming.rb
  95. +3 −1 activemodel/lib/active_model/validations/confirmation.rb
  96. +30 −0 activemodel/test/cases/callbacks_test.rb
  97. +1 −1  activerecord/activerecord.gemspec
  98. +1 −1  activerecord/examples/performance.rb
  99. +3 −3 activerecord/lib/active_record/association_preload.rb
  100. +1 −1  activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
  101. +12 −10 activerecord/lib/active_record/base.rb
  102. +1 −1  activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
  103. +6 −14 activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
  104. +11 −7 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  105. +29 −24 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  106. +2 −5 activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
  107. +2 −2 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
  108. +20 −17 activerecord/lib/active_record/dynamic_finder_match.rb
  109. +6 −15 activerecord/lib/active_record/dynamic_scope_match.rb
  110. +3 −5 activerecord/lib/active_record/fixtures.rb
  111. +6 −1 activerecord/lib/active_record/nested_attributes.rb
  112. +1 −1  activerecord/lib/active_record/railtie.rb
  113. +2 −2 activerecord/lib/active_record/railties/databases.rake
  114. +5 −10 activerecord/lib/active_record/relation.rb
  115. +11 −6 activerecord/lib/active_record/relation/calculations.rb
  116. +17 −41 activerecord/lib/active_record/relation/query_methods.rb
  117. +1 −1  activerecord/lib/active_record/serialization.rb
  118. +5 −0 activerecord/test/cases/associations/belongs_to_associations_test.rb
  119. +10 −0 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  120. +12 −0 activerecord/test/cases/associations/has_many_associations_test.rb
  121. +14 −0 activerecord/test/cases/associations/has_many_through_associations_test.rb
  122. +5 −0 activerecord/test/cases/associations/has_one_associations_test.rb
  123. +22 −0 activerecord/test/cases/base_test.rb
  124. +98 −0 activerecord/test/cases/dynamic_finder_match_test.rb
  125. +0 −51 activerecord/test/cases/finder_test.rb
  126. +1 −1  activerecord/test/cases/method_scoping_test.rb
  127. +20 −3 activerecord/test/cases/migration_test.rb
  128. +17 −1 activerecord/test/cases/nested_attributes_test.rb
  129. +5 −0 activerecord/test/cases/relations_test.rb
  130. +35 −14 activeresource/lib/active_resource/base.rb
  131. +5 −5 activeresource/lib/active_resource/connection.rb
  132. +3 −0  activeresource/lib/active_resource/exceptions.rb
  133. +7 −0 activeresource/test/abstract_unit.rb
  134. +19 −0 activeresource/test/cases/base_test.rb
  135. +1 −1  activeresource/test/cases/finder_test.rb
  136. +1 −1  activeresource/test/cases/format_test.rb
  137. +5 −1 activeresource/test/fixtures/sound.rb
  138. +1 −1  activesupport/lib/active_support/callbacks.rb
  139. +22 −2 activesupport/lib/active_support/configurable.rb
  140. +22 −1 activesupport/lib/active_support/core_ext/class/attribute.rb
  141. +6 −4 activesupport/lib/active_support/core_ext/hash/keys.rb
  142. +13 −6 activesupport/lib/active_support/core_ext/module/attr_internal.rb
  143. +3 −2 activesupport/lib/active_support/core_ext/object/to_param.rb
  144. +8 −0 activesupport/lib/active_support/core_ext/uri.rb
  145. +16 −2 activesupport/lib/active_support/ordered_options.rb
  146. +23 −0 activesupport/test/callbacks_test.rb
  147. +18 −0 activesupport/test/configurable_test.rb
  148. +8 −4 activesupport/test/core_ext/hash_ext_test.rb
  149. +8 −11 railties/guides/source/action_controller_overview.textile
  150. +30 −0 railties/guides/source/action_mailer_basics.textile
  151. +3 −3 railties/guides/source/active_record_querying.textile
  152. +56 −31 railties/guides/source/association_basics.textile
  153. +1 −12 railties/guides/source/caching_with_rails.textile
  154. +18 −11 railties/guides/source/form_helpers.textile
  155. +32 −33 railties/guides/source/layouts_and_rendering.textile
  156. +19 −19 railties/guides/source/routing.textile
  157. +2 −11 railties/lib/rails/application.rb
  158. +1 −0  railties/lib/rails/application/configuration.rb
  159. +55 −0 railties/lib/rails/application/routes_reloader.rb
  160. +18 −1 railties/lib/rails/commands.rb
  161. +1 −1  railties/lib/rails/commands/plugin.rb
  162. +19 −13 railties/lib/rails/engine.rb
  163. +1 −0  railties/lib/rails/generators/rails/app/templates/Gemfile
  164. +16 −3 railties/lib/rails/railtie/configuration.rb
  165. +1 −1  railties/lib/rails/test_unit/railtie.rb
  166. +99 −0 railties/test/railties/engine_test.rb
View
9 actionmailer/lib/action_mailer/base.rb
@@ -409,7 +409,7 @@ def respond_to?(method, *args) #:nodoc:
protected
def set_payload_for_mail(payload, mail) #:nodoc:
- payload[:mailer] = self.name
+ payload[:mailer] = name
payload[:message_id] = mail.message_id
payload[:subject] = mail.subject
payload[:to] = mail.to
@@ -421,11 +421,8 @@ def set_payload_for_mail(payload, mail) #:nodoc:
end
def method_missing(method, *args) #:nodoc:
- if action_methods.include?(method.to_s)
- new(method, *args).message
- else
- super
- end
+ return super unless respond_to?(method)
+ new(method, *args).message
end
end
View
10 actionmailer/lib/action_mailer/railtie.rb
@@ -18,6 +18,10 @@ class Railtie < Rails::Railtie
options.javascripts_dir ||= paths.public.javascripts.to_a.first
options.stylesheets_dir ||= paths.public.stylesheets.to_a.first
+ # make sure readers methods get compiled
+ options.asset_path ||= nil
+ options.asset_host ||= nil
+
ActiveSupport.on_load(:action_mailer) do
include AbstractController::UrlFor
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
@@ -25,5 +29,11 @@ class Railtie < Rails::Railtie
options.each { |k,v| send("#{k}=", v) }
end
end
+
+ initializer "action_mailer.compile_config_methods" do
+ ActiveSupport.on_load(:action_mailer) do
+ config.compile_methods! if config.respond_to?(:compile_methods!)
+ end
+ end
end
end
View
2  actionpack/Rakefile
@@ -18,7 +18,7 @@ Rake::TestTask.new(:test_action_pack) do |t|
# this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob('test/{abstract,controller,dispatch,template}/**/*_test.rb').sort
- #t.warning = true
+ t.warning = true
t.verbose = true
end
View
8 actionpack/lib/abstract_controller/base.rb
@@ -61,13 +61,13 @@ def hidden_actions
def action_methods
@action_methods ||= begin
# All public instance methods of this class, including ancestors
- methods = public_instance_methods(true).map { |m| m.to_s }.to_set -
+ methods = (public_instance_methods(true) -
# Except for public instance methods of Base and its ancestors
- internal_methods.map { |m| m.to_s } +
+ internal_methods +
# Be sure to include shadowed public instance methods of this class
- public_instance_methods(false).map { |m| m.to_s } -
+ public_instance_methods(false)).uniq.map { |x| x.to_s } -
# And always exclude explicitly hidden actions
- hidden_actions
+ hidden_actions.to_a
# Clear out AS callback method pollution
methods.reject { |method| method =~ /_one_time_conditions/ }
View
3  actionpack/lib/abstract_controller/layouts.rb
@@ -347,8 +347,7 @@ def _default_layout(require_layout = false)
begin
layout_name = _layout if action_has_layout?
rescue NameError => e
- raise NoMethodError,
- "You specified #{@_layout.inspect} as the layout, but no such method was found"
+ raise e, "Could not render layout: #{e.message}"
end
if require_layout && action_has_layout? && !layout_name
View
1  actionpack/lib/abstract_controller/url_for.rb
@@ -1,7 +1,6 @@
module AbstractController
module UrlFor
extend ActiveSupport::Concern
-
include ActionDispatch::Routing::UrlFor
def _routes
View
1  actionpack/lib/action_controller.rb
@@ -72,4 +72,5 @@ module ActionController
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/name_error'
+require 'active_support/core_ext/uri'
require 'active_support/inflector'
View
2  actionpack/lib/action_controller/caching/actions.rb
@@ -161,7 +161,7 @@ def initialize(controller, options = {}, infer_extension = true)
def normalize!(path)
path << 'index' if path[-1] == ?/
path << ".#{extension}" if extension and !path.ends_with?(extension)
- URI.unescape(path)
+ URI.parser.unescape(path)
end
end
end
View
3  actionpack/lib/action_controller/caching/pages.rb
@@ -1,5 +1,4 @@
require 'fileutils'
-require 'uri'
require 'active_support/core_ext/class/attribute_accessors'
module ActionController #:nodoc:
@@ -99,7 +98,7 @@ def caches_page(*actions)
private
def page_cache_file(path)
- name = (path.empty? || path == "/") ? "/index" : URI.unescape(path.chomp('/'))
+ name = (path.empty? || path == "/") ? "/index" : URI.parser.unescape(path.chomp('/'))
name << page_cache_extension unless (name.split('/').last || name).include? '.'
return name
end
View
5 actionpack/lib/action_controller/metal.rb
@@ -85,6 +85,9 @@ def controller_name
def initialize(*)
@_headers = {"Content-Type" => "text/html"}
@_status = 200
+ @_request = nil
+ @_response = nil
+ @_routes = nil
super
end
@@ -99,7 +102,7 @@ def params=(val)
# Basic implementations for content_type=, location=, and headers are
# provided to reduce the dependency on the RackDelegation module
# in Renderer and Redirector.
-
+
def content_type=(type)
headers["Content-Type"] = type.to_s
end
View
6 actionpack/lib/action_controller/metal/helpers.rb
@@ -96,9 +96,9 @@ def all_application_helpers
def all_helpers_from_path(path)
helpers = []
- Array.wrap(path).each do |path|
- extract = /^#{Regexp.quote(path.to_s)}\/?(.*)_helper.rb$/
- helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
+ Array.wrap(path).each do |_path|
+ extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/
+ helpers += Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
helpers.sort!
helpers.uniq!
View
22 actionpack/lib/action_controller/metal/http_authentication.rb
@@ -214,7 +214,7 @@ def ha1(credentials, password)
def encode_credentials(http_method, credentials, password, password_is_ha1)
credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1)
- "Digest " + credentials.sort_by {|x| x[0].to_s }.inject([]) {|a, v| a << "#{v[0]}='#{v[1]}'" }.join(', ')
+ "Digest " + credentials.sort_by {|x| x[0].to_s }.map {|v| "#{v[0]}='#{v[1]}'" }.join(', ')
end
def decode_credentials_header(request)
@@ -423,14 +423,13 @@ def authenticate(controller, &login_procedure)
# Returns nil if no token is found.
def token_and_options(request)
if header = request.authorization.to_s[/^Token (.*)/]
- values = $1.split(',').
- inject({}) do |memo, value|
- value.strip! # remove any spaces between commas and values
- key, value = value.split(/\=\"?/) # split key=value pairs
- value.chomp!('"') # chomp trailing " in value
- value.gsub!(/\\\"/, '"') # unescape remaining quotes
- memo.update(key => value)
- end
+ values = Hash[$1.split(',').map do |value|
+ value.strip! # remove any spaces between commas and values
+ key, value = value.split(/\=\"?/) # split key=value pairs
+ value.chomp!('"') # chomp trailing " in value
+ value.gsub!(/\\\"/, '"') # unescape remaining quotes
+ [key, value]
+ end]
[values.delete("token"), values.with_indifferent_access]
end
end
@@ -442,9 +441,8 @@ def token_and_options(request)
#
# Returns String.
def encode_credentials(token, options = {})
- values = ["token=#{token.to_s.inspect}"]
- options.each do |key, value|
- values << "#{key}=#{value.to_s.inspect}"
+ values = ["token=#{token.to_s.inspect}"] + options.map do |key, value|
+ "#{key}=#{value.to_s.inspect}"
end
"Token #{values * ", "}"
end
View
2  actionpack/lib/action_controller/metal/renderers.rb
@@ -71,7 +71,7 @@ def self._write_render_options
end
add :json do |json, options|
- json = ActiveSupport::JSON.encode(json, options) unless json.respond_to?(:to_str)
+ json = json.to_json(options) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = json
View
18 actionpack/lib/action_controller/metal/url_for.rb
@@ -5,16 +5,20 @@ module UrlFor
include AbstractController::UrlFor
def url_options
- options = {}
- if _routes.equal?(env["action_dispatch.routes"])
- options[:script_name] = request.script_name.dup
- end
-
- super.merge(options).reverse_merge(
+ @_url_options ||= super.reverse_merge(
:host => request.host_with_port,
:protocol => request.protocol,
:_path_segments => request.symbolized_path_parameters
- )
+ ).freeze
+
+ if _routes.equal?(env["action_dispatch.routes"])
+ @_url_options.dup.tap do |options|
+ options[:script_name] = request.script_name.dup
+ options.freeze
+ end
+ else
+ @_url_options
+ end
end
end
end
View
10 actionpack/lib/action_controller/railtie.rb
@@ -26,6 +26,10 @@ class Railtie < Rails::Railtie
options.stylesheets_dir ||= paths.public.stylesheets.to_a.first
options.page_cache_directory ||= paths.public.to_a.first
+ # make sure readers methods get compiled
+ options.asset_path ||= nil
+ options.asset_host ||= nil
+
ActiveSupport.on_load(:action_controller) do
include app.routes.mounted_helpers
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
@@ -33,5 +37,11 @@ class Railtie < Rails::Railtie
options.each { |k,v| send("#{k}=", v) }
end
end
+
+ initializer "action_controller.compile_config_methods" do
+ ActiveSupport.on_load(:action_controller) do
+ config.compile_methods! if config.respond_to?(:compile_methods!)
+ end
+ end
end
end
View
14 actionpack/lib/action_controller/test_case.rb
@@ -127,7 +127,7 @@ def initialize(env = {})
class Result < ::Array #:nodoc:
def to_s() join '/' end
def self.new_escaped(strings)
- new strings.collect {|str| URI.unescape str}
+ new strings.collect {|str| uri_parser.unescape str}
end
end
@@ -394,7 +394,7 @@ def process(action, parameters = nil, session = nil, flash = nil, http_method =
parameters ||= {}
@request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
- @request.session = ActionController::TestSession.new(session) unless session.nil?
+ @request.session = ActionController::TestSession.new(session) if session
@request.session["flash"] = @request.flash.update(flash || {})
@request.session["flash"].sweep
@@ -417,7 +417,7 @@ def setup_controller_request_and_response
@request.env.delete('PATH_INFO')
- if @controller
+ if defined?(@controller) && @controller
@controller.request = @request
@controller.params = {}
end
@@ -462,9 +462,11 @@ def build_request_uri(action, parameters)
# The exception is stored in the exception accessor for further inspection.
module RaiseActionExceptions
def self.included(base)
- base.class_eval do
- attr_accessor :exception
- protected :exception, :exception=
+ unless base.method_defined?(:exception) && base.method_defined?(:exception=)
+ base.class_eval do
+ attr_accessor :exception
+ protected :exception, :exception=
+ end
end
end
View
8 actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
@@ -18,14 +18,14 @@ def initialize(hash)
hash[k] = Conditions.new(v)
when :children
hash[k] = v = keys_to_symbols(v)
- v.each do |k,v2|
- case k
+ v.each do |key,value|
+ case key
when :count, :greater_than, :less_than
# keys are valid, and require no further processing
when :only
- v[k] = Conditions.new(v2)
+ v[key] = Conditions.new(value)
else
- raise "illegal key #{k.inspect} => #{v2.inspect}"
+ raise "illegal key #{key.inspect} => #{value.inspect}"
end
end
else
View
19 actionpack/lib/action_dispatch/http/request.rb
@@ -54,11 +54,7 @@ def key?(key)
# the application should use), this \method returns the overridden
# value, not the original.
def request_method
- @request_method ||= begin
- method = env["REQUEST_METHOD"]
- HTTP_METHOD_LOOKUP[method] || raise(ActionController::UnknownHttpMethod, "#{method}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
- method
- end
+ @request_method ||= check_method(env["REQUEST_METHOD"])
end
# Returns a symbol form of the #request_method
@@ -70,11 +66,7 @@ def request_method_symbol
# even if it was overridden by middleware. See #request_method for
# more information.
def method
- @method ||= begin
- method = env["rack.methodoverride.original_method"] || env['REQUEST_METHOD']
- HTTP_METHOD_LOOKUP[method] || raise(ActionController::UnknownHttpMethod, "#{method}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
- method
- end
+ @method ||= check_method(env["rack.methodoverride.original_method"] || env['REQUEST_METHOD'])
end
# Returns a symbol form of the #method
@@ -246,5 +238,12 @@ def authorization
def local?
LOCALHOST.any? { |local_ip| local_ip === remote_addr && local_ip === remote_ip }
end
+
+ private
+
+ def check_method(name)
+ HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
+ name
+ end
end
end
View
1  actionpack/lib/action_dispatch/http/response.rb
@@ -140,7 +140,6 @@ def to_a
assign_default_content_type_and_charset!
handle_conditional_get!
self["Set-Cookie"] = self["Set-Cookie"].join("\n") if self["Set-Cookie"].respond_to?(:join)
- self["ETag"] = @_etag if @_etag
super
end
View
4 actionpack/lib/action_dispatch/http/url.rb
@@ -15,12 +15,12 @@ def scheme
# Returns 'https://' if this is an SSL request and 'http://' otherwise.
def protocol
- ssl? ? 'https://' : 'http://'
+ @protocol ||= ssl? ? 'https://' : 'http://'
end
# Is this an SSL request?
def ssl?
- @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
+ @ssl ||= @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
end
# Returns the \host for this request, such as "example.com".
View
8 actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -19,9 +19,11 @@ class Callbacks
# replace the existing callback. Passing an identifier is a suggested
# practice if the code adding a preparation block may be reloaded.
def self.to_prepare(*args, &block)
- if args.first.is_a?(Symbol) && block_given?
- define_method :"__#{args.first}", &block
- set_callback(:prepare, :"__#{args.first}")
+ first_arg = args.first
+ if first_arg.is_a?(Symbol) && block_given?
+ remove_method :"__#{first_arg}" if method_defined?(:"__#{first_arg}")
+ define_method :"__#{first_arg}", &block
+ set_callback(:prepare, :"__#{first_arg}")
else
set_callback(:prepare, *args, &block)
end
View
6 actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -102,8 +102,8 @@ def loaded?
def destroy
clear
- @by.send(:destroy, @env) if @by
- @env[ENV_SESSION_OPTIONS_KEY][:id] = nil if @env && @env[ENV_SESSION_OPTIONS_KEY]
+ @by.send(:destroy, @env) if defined?(@by) && @by
+ @env[ENV_SESSION_OPTIONS_KEY][:id] = nil if defined?(@env) && @env && @env[ENV_SESSION_OPTIONS_KEY]
@loaded = false
end
@@ -165,7 +165,7 @@ def call(env)
return response unless value
cookie = { :value => value }
- unless options[:expire_after].nil?
+ if options[:expire_after]
cookie[:expires] = Time.now + options.delete(:expire_after)
end
View
9 actionpack/lib/action_dispatch/middleware/stack.rb
@@ -41,9 +41,12 @@ def normalize(object)
end
end
- def initialize(*args, &block)
- super(*args)
- block.call(self) if block_given?
+ # Use this instead of super to work around a warning.
+ alias :array_initialize :initialize
+
+ def initialize(*args)
+ array_initialize(*args)
+ yield(self) if block_given?
end
def insert(index, *args, &block)
View
2  actionpack/lib/action_dispatch/middleware/static.rb
@@ -4,7 +4,7 @@ module ActionDispatch
class FileHandler
def initialize(at, root)
@at, @root = at.chomp('/'), root.chomp('/')
- @compiled_at = Regexp.compile(/^#{Regexp.escape(at)}/) unless @at.blank?
+ @compiled_at = (Regexp.compile(/^#{Regexp.escape(at)}/) unless @at.blank?)
@compiled_root = Regexp.compile(/^#{Regexp.escape(root)}/)
@file_server = ::Rack::File.new(root)
end
View
4 actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
@@ -14,7 +14,7 @@
def debug_hash(hash)
hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
- end
+ end unless self.class.method_defined?(:debug_hash)
%>
<h2 style="margin-top: 30px">Request</h2>
@@ -28,4 +28,4 @@
<h2 style="margin-top: 30px">Response</h2>
-<p><b>Headers</b>: <pre><%=h @response ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
+<p><b>Headers</b>: <pre><%=h defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
View
6 actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
@@ -12,14 +12,14 @@
<div id="traces">
<% names.each do |name| %>
<%
- show = "document.getElementById('#{name.gsub /\s/, '-'}').style.display='block';"
- hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub /\s/, '-'}').style.display='none';"}
+ show = "document.getElementById('#{name.gsub(/\s/, '-')}').style.display='block';"
+ hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub(/\s/, '-')}').style.display='none';"}
%>
<a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
<% end %>
<% traces.each do |name, trace| %>
- <div id="<%= name.gsub /\s/, '-' %>" style="display: <%= name == "Application Trace" ? 'block' : 'none' %>;">
+ <div id="<%= name.gsub(/\s/, '-') %>" style="display: <%= (name == "Application Trace") ? 'block' : 'none' %>;">
<pre><code><%=h trace.join "\n" %></code></pre>
</div>
<% end %>
View
48 actionpack/lib/action_dispatch/routing/mapper.rb
@@ -62,7 +62,6 @@ def normalize_options!
if using_match_shorthand?(path_without_format, @options)
to_shorthand = @options[:to].blank?
@options[:to] ||= path_without_format[1..-1].sub(%r{/([^/]*)$}, '#\1')
- @options[:as] ||= Mapper.normalize_name(path_without_format)
end
@options.merge!(default_controller_and_action(to_shorthand))
@@ -346,11 +345,11 @@ def delete(*args, &block)
# Redirect any path to another path:
#
# match "/stories" => redirect("/posts")
- def redirect(*args, &block)
+ def redirect(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
- path = args.shift || block
- path_proc = path.is_a?(Proc) ? path : proc { |params| path % params }
+ path = args.shift || Proc.new
+ path_proc = path.is_a?(Proc) ? path : proc { |params| (params.empty? || !path.match(/%\{\w*\}/)) ? path : (path % params) }
status = options[:status] || 301
lambda do |env|
@@ -395,10 +394,10 @@ def map_method(method, *args, &block)
# namespace "admin" do
# resources :posts, :comments
# end
- #
+ #
# This will create a number of routes for each of the posts and comments
# controller. For Admin::PostsController, Rails will create:
- #
+ #
# GET /admin/photos
# GET /admin/photos/new
# POST /admin/photos
@@ -406,33 +405,33 @@ def map_method(method, *args, &block)
# GET /admin/photos/1/edit
# PUT /admin/photos/1
# DELETE /admin/photos/1
- #
+ #
# If you want to route /photos (without the prefix /admin) to
# Admin::PostsController, you could use
- #
+ #
# scope :module => "admin" do
# resources :posts, :comments
# end
#
# or, for a single case
- #
+ #
# resources :posts, :module => "admin"
- #
+ #
# If you want to route /admin/photos to PostsController
# (without the Admin:: module prefix), you could use
- #
+ #
# scope "/admin" do
# resources :posts, :comments
# end
#
# or, for a single case
- #
+ #
# resources :posts, :path => "/admin"
#
# In each of these cases, the named routes remain the same as if you did
# not use scope. In the last case, the following paths map to
# PostsController:
- #
+ #
# GET /admin/photos
# GET /admin/photos/new
# POST /admin/photos
@@ -676,6 +675,7 @@ class SingletonResource < Resource #:nodoc:
DEFAULT_ACTIONS = [:show, :create, :update, :destroy, :new, :edit]
def initialize(entities, options)
+ @as = nil
@name = entities.to_s
@path = (options.delete(:path) || @name).to_s
@controller = (options.delete(:controller) || plural).to_s
@@ -923,9 +923,14 @@ def match(*args)
if action.to_s =~ /^[\w\/]+$/
options[:action] ||= action unless action.to_s.include?("/")
- options[:as] = name_for_action(action, options[:as])
else
- options[:as] = name_for_action(options[:as])
+ action = nil
+ end
+
+ if options.key?(:as) && !options[:as]
+ options.delete(:as)
+ else
+ options[:as] = name_for_action(options[:as], action)
end
super(path, options)
@@ -1091,18 +1096,16 @@ def action_path(name, path = nil)
path || @scope[:path_names][name.to_sym] || name.to_s
end
- def prefix_name_for_action(action, as)
- if as.present?
+ def prefix_name_for_action(as, action)
+ if as
as.to_s
- elsif as
- nil
elsif !canonical_action?(action, @scope[:scope_level])
action.to_s
end
end
- def name_for_action(action, as=nil)
- prefix = prefix_name_for_action(action, as)
+ def name_for_action(as, action)
+ prefix = prefix_name_for_action(as, action)
prefix = Mapper.normalize_name(prefix) if prefix
name_prefix = @scope[:as]
@@ -1126,7 +1129,8 @@ def name_for_action(action, as=nil)
[name_prefix, member_name, prefix]
end
- name.select(&:present?).join("_").presence
+ candidate = name.select(&:present?).join("_").presence
+ candidate unless as.nil? && @set.routes.find { |r| r.name == candidate }
end
end
View
10 actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -105,7 +105,7 @@ def polymorphic_url(record_or_hash_or_array, options = {})
else [ record_or_hash_or_array ]
end
- inflection = if options[:action].to_s == "new"
+ inflection = if options[:action] && options[:action].to_s == "new"
args.pop
:singular
elsif (record.respond_to?(:persisted?) && !record.persisted?)
@@ -168,10 +168,7 @@ def routing_type(options)
end
def build_named_route_call(records, inflection, options = {})
- unless records.is_a?(Array)
- record = extract_record(records)
- route = []
- else
+ if records.is_a?(Array)
record = records.pop
route = records.map do |parent|
if parent.is_a?(Symbol) || parent.is_a?(String)
@@ -180,6 +177,9 @@ def build_named_route_call(records, inflection, options = {})
ActiveModel::Naming.route_key(parent).singularize
end
end
+ else
+ record = extract_record(records)
+ route = []
end
if record.is_a?(Symbol) || record.is_a?(String)
View
46 actionpack/lib/action_dispatch/routing/route_set.rb
@@ -1,6 +1,7 @@
require 'rack/mount'
require 'forwardable'
require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/hash/slice'
module ActionDispatch
module Routing
@@ -66,7 +67,7 @@ def merge_default_action!(params)
end
def split_glob_param!(params)
- params[@glob_param] = params[@glob_param].split('/').map { |v| URI.unescape(v) }
+ params[@glob_param] = params[@glob_param].split('/').map { |v| URI.parser.unescape(v) }
end
end
@@ -157,6 +158,7 @@ def define_hash_access(route, name, kind, options)
# We use module_eval to avoid leaks
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
+ remove_method :#{selector} if method_defined?(:#{selector})
def #{selector}(*args)
options = args.extract_options!
@@ -190,6 +192,7 @@ def define_url_helper(route, name, kind, options)
hash_access_method = hash_access_name(name, kind)
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
+ remove_method :#{selector} if method_defined?(:#{selector})
def #{selector}(*args)
url_for(#{hash_access_method}(*args))
end
@@ -300,9 +303,9 @@ def url_helpers
extend ActiveSupport::Concern
include UrlFor
- @routes = routes
+ @_routes = routes
class << self
- delegate :url_for, :to => '@routes'
+ delegate :url_for, :to => '@_routes'
end
extend routes.named_routes.module
@@ -311,7 +314,7 @@ class << self
# Yes plz - JP
included do
routes.install_helpers(self)
- singleton_class.send(:define_method, :_routes) { routes }
+ singleton_class.send(:redefine_method, :_routes) { routes }
end
define_method(:_routes) { @_routes || routes }
@@ -334,6 +337,19 @@ def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil
end
class Generator #:nodoc:
+ PARAMETERIZE = {
+ :parameterize => lambda do |name, value|
+ if name == :controller
+ value
+ elsif value.is_a?(Array)
+ value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
+ else
+ return nil unless param = value.to_param
+ param.split('/').map { |v| Rack::Mount::Utils.escape_uri(v) }.join("/")
+ end
+ end
+ }
+
attr_reader :options, :recall, :set, :named_route
def initialize(options, recall, set, extras = false)
@@ -422,7 +438,7 @@ def handle_nil_action!
end
def generate
- path, params = @set.set.generate(:path_info, named_route, options, recall, opts)
+ path, params = @set.set.generate(:path_info, named_route, options, recall, PARAMETERIZE)
raise_routing_error unless path
@@ -430,26 +446,12 @@ def generate
return [path, params.keys] if @extras
- path << "?#{params.to_query}" if params.any?
+ path << "?#{params.to_query}" unless params.empty?
path
rescue Rack::Mount::RoutingError
raise_routing_error
end
- def opts
- parameterize = lambda do |name, value|
- if name == :controller
- value
- elsif value.is_a?(Array)
- value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
- else
- return nil unless param = value.to_param
- param.split('/').map { |v| Rack::Mount::Utils.escape_uri(v) }.join("/")
- end
- end
- {:parameterize => parameterize}
- end
-
def raise_routing_error
raise ActionController::RoutingError.new("No route matches #{options.inspect}")
end
@@ -510,7 +512,7 @@ def url_for(options)
end
script_name = options.delete(:script_name)
- path = (script_name.blank? ? _generate_prefix(options) : script_name).to_s
+ path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s
path_options = options.except(*RESERVED_OPTIONS)
path_options = yield(path_options) if block_given?
@@ -543,7 +545,7 @@ def recognize_path(path, environment = {})
params.each do |key, value|
if value.is_a?(String)
value = value.dup.force_encoding(Encoding::BINARY) if value.encoding_aware?
- params[key] = URI.unescape(value)
+ params[key] = URI.parser.unescape(value)
end
end
View
5 actionpack/lib/action_dispatch/routing/url_for.rb
@@ -98,6 +98,11 @@ module UrlFor
end
end
+ def initialize(*)
+ @_routes = nil
+ super
+ end
+
def url_options
default_url_options
end
View
8 actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -81,14 +81,10 @@ def parameterize(value)
def normalize_argument_to_redirection(fragment)
case fragment
- when %r{^\w[\w\d+.-]*:.*}
+ when %r{^\w[A-Za-z\d+.-]*:.*}
fragment
when String
- if fragment =~ %r{^\w[\w\d+.-]*:.*}
- fragment
- else
- @request.protocol + @request.host_with_port + fragment
- end
+ @request.protocol + @request.host_with_port + fragment
when :back
raise RedirectBackError unless refer = @request.headers["Referer"]
refer
View
24 actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -146,16 +146,16 @@ def assert_routing(path, options, defaults={}, extras={}, message=nil)
#
def with_routing
old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
- old_controller, @controller = @controller, @controller.clone if @controller
- _routes = @routes
-
- # Unfortunately, there is currently an abstraction leak between AC::Base
- # and AV::Base which requires having the URL helpers in both AC and AV.
- # To do this safely at runtime for tests, we need to bump up the helper serial
- # to that the old AV subclass isn't cached.
- #
- # TODO: Make this unnecessary
- if @controller
+ if defined?(@controller) && @controller
+ old_controller, @controller = @controller, @controller.clone
+ _routes = @routes
+
+ # Unfortunately, there is currently an abstraction leak between AC::Base
+ # and AV::Base which requires having the URL helpers in both AC and AV.
+ # To do this safely at runtime for tests, we need to bump up the helper serial
+ # to that the old AV subclass isn't cached.
+ #
+ # TODO: Make this unnecessary
@controller.singleton_class.send(:include, _routes.url_helpers)
@controller.view_context_class = Class.new(@controller.view_context_class) do
include _routes.url_helpers
@@ -164,14 +164,14 @@ def with_routing
yield @routes
ensure
@routes = old_routes
- if @controller
+ if defined?(@controller) && @controller
@controller = old_controller
end
end
# ROUTES TODO: These assertions should really work in an integration context
def method_missing(selector, *args, &block)
- if @controller && @routes && @routes.named_routes.helpers.include?(selector)
+ if defined?(@controller) && @controller && @routes && @routes.named_routes.helpers.include?(selector)
@controller.send(selector, *args, &block)
else
super
View
8 actionpack/lib/action_dispatch/testing/assertions/selector.rb
@@ -67,7 +67,7 @@ def css_select(*args)
arg = args.shift
elsif arg == nil
raise ArgumentError, "First argument is either selector or element to select, but nil found. Perhaps you called assert_select with an element that does not exist?"
- elsif @selected
+ elsif defined?(@selected) && @selected
matches = []
@selected.each do |selected|
@@ -187,6 +187,7 @@ def css_select(*args)
def assert_select(*args, &block)
# Start with optional element followed by mandatory selector.
arg = args.shift
+ @selected ||= nil
if arg.is_a?(HTML::Node)
# First argument is a node (tag or text, but also HTML root),
@@ -442,6 +443,7 @@ def assert_select_rjs(*args, &block)
assert_block("") { true } # to count the assertion
if block_given? && !([:remove, :show, :hide, :toggle].include? rjs_type)
begin
+ @selected ||= nil
in_scope, @selected = @selected, matches
yield matches
ensure
@@ -513,8 +515,8 @@ def assert_select_encoded(element = nil, &block)
node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { Rack::Utils.escapeHTML($1) }
end
- selected = elements.map do |element|
- text = element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
+ selected = elements.map do |_element|
+ text = _element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
root = HTML::Document.new(CGI.unescapeHTML("<encoded>#{text}</encoded>")).root
css_select(root, "encoded:root", &block)[0]
end
View
33 actionpack/lib/action_dispatch/testing/integration.rb
@@ -171,6 +171,7 @@ def cookies
# Create and initialize a new Session instance.
def initialize(app)
+ super()
@app = app
# If the app is a Rails app, make url_helpers available on the session
@@ -182,6 +183,7 @@ def initialize(app)
reset!
end
+ remove_method :default_url_options
def default_url_options
{ :host => host, :protocol => https? ? "https" : "http" }
end
@@ -257,19 +259,19 @@ def process(method, path, parameters = nil, rack_environment = nil)
end
end
- port = host.split(':')[1]
+ hostname, port = host.split(':')
env = {
:method => method,
:params => parameters,
- "SERVER_NAME" => host.split(':')[0],
- "SERVER_PORT" => (port ? port : (https? ? "443" : "80")),
+ "SERVER_NAME" => hostname,
+ "SERVER_PORT" => port || (https? ? "443" : "80"),
"HTTPS" => https? ? "on" : "off",
"rack.url_scheme" => https? ? "https" : "http",
"REQUEST_URI" => path,
- "HTTP_HOST" => [host, port].compact.join(':'),
+ "HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
"HTTP_ACCEPT" => accept
@@ -307,7 +309,7 @@ module Runner
include ActionDispatch::Assertions
def app
- @app
+ @app ||= nil
end
# Reset the current session. This is useful for testing multiple sessions
@@ -319,10 +321,10 @@ def reset!
%w(get post put head delete cookies assigns
xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
define_method(method) do |*args|
- reset! unless @integration_session
+ reset! unless integration_session
# reset the html_document variable, but only for new get/post calls
@html_document = nil unless %w(cookies assigns).include?(method)
- @integration_session.__send__(method, *args).tap do
+ integration_session.__send__(method, *args).tap do
copy_session_variables!
end
end
@@ -347,7 +349,7 @@ def open_session(app = nil)
# Copy the instance variables from the current session instance into the
# test instance.
def copy_session_variables! #:nodoc:
- return unless @integration_session
+ return unless integration_session
%w(controller response request).each do |var|
instance_variable_set("@#{var}", @integration_session.__send__(var))
end
@@ -357,21 +359,26 @@ def copy_session_variables! #:nodoc:
include ActionDispatch::Routing::UrlFor
def url_options
- reset! unless @integration_session
- @integration_session.url_options
+ reset! unless integration_session
+ integration_session.url_options
end
# Delegate unhandled messages to the current session instance.
def method_missing(sym, *args, &block)
- reset! unless @integration_session
- if @integration_session.respond_to?(sym)
- @integration_session.__send__(sym, *args, &block).tap do
+ reset! unless integration_session
+ if integration_session.respond_to?(sym)
+ integration_session.__send__(sym, *args, &block).tap do
copy_session_variables!
end
else
super
end
end
+
+ private
+ def integration_session
+ @integration_session ||= nil
+ end
end
end
View
3  actionpack/lib/action_dispatch/testing/test_request.rb
@@ -13,6 +13,7 @@ def initialize(env = {})
env = Rails.application.env_config.merge(env) if defined?(Rails.application)
super(DEFAULT_ENV.merge(env))
+ @cookies = nil
self.host = 'test.host'
self.remote_addr = '0.0.0.0'
self.user_agent = 'Rails Testing'
@@ -66,7 +67,7 @@ def user_agent=(user_agent)
def accept=(mime_types)
@env.delete('action_dispatch.request.accepts')
- @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
+ @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_type| mime_type.to_s }.join(",")
end
def cookies
View
3  actionpack/lib/action_view/base.rb
@@ -209,8 +209,7 @@ def initialize(lookup_context = nil, assigns_for_first_render = {}, controller =
@_request = controller.request if controller.respond_to?(:request)
end
- config = controller && controller.respond_to?(:config) ? controller.config : {}
- @_config = ActiveSupport::InheritableOptions.new(config)
+ @_config = controller && controller.respond_to?(:config) ? controller.config.inheritable_copy : {}
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
@_virtual_path = nil
View
30 actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -705,19 +705,29 @@ def audio_tag(source, options = {})
private
- def rewrite_extension?(source, dir, ext)
- source_ext = File.extname(source)[1..-1]
- ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}"))))
+ def rewrite_extension(source, dir, ext)
+ source_ext = File.extname(source)
+
+ if source_ext.empty?
+ "#{source}.#{ext}"
+ elsif ext != source_ext[1..-1]
+ with_ext = "#{source}.#{ext}"
+ with_ext if File.exist?(File.join(config.assets_dir, dir, with_ext))
+ end || source
end
def rewrite_host_and_protocol(source, has_request)
host = compute_asset_host(source)
- if has_request && host.present? && !is_uri?(host)
+ if has_request && host && !is_uri?(host)
host = "#{controller.request.protocol}#{host}"
end
"#{host}#{source}"
end
+ def rewrite_relative_url_root(source, relative_url_root)
+ relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source
+ end
+
# Add the the extension +ext+ if not present. Return full URLs otherwise untouched.
# Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
# roots. Rewrite the asset path for cache-busting asset ids. Include
@@ -725,17 +735,15 @@ def rewrite_host_and_protocol(source, has_request)
def compute_public_path(source, dir, ext = nil, include_host = true)
return source if is_uri?(source)
- source += ".#{ext}" if rewrite_extension?(source, dir, ext)
- source = "/#{dir}/#{source}" unless source[0] == ?/
+ source = rewrite_extension(source, dir, ext) if ext
+ source = "/#{dir}/#{source}" unless source[0] == ?/
if controller.respond_to?(:env) && controller.env["action_dispatch.asset_path"]
source = rewrite_asset_path(source, controller.env["action_dispatch.asset_path"])
end
source = rewrite_asset_path(source, config.asset_path)
has_request = controller.respond_to?(:request)
- if has_request && include_host && source !~ %r{^#{controller.config.relative_url_root}/}
- source = "#{controller.config.relative_url_root}#{source}"
- end
+ source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request && include_host
source = rewrite_host_and_protocol(source, has_request) if include_host
source
@@ -802,10 +810,10 @@ def rewrite_asset_path(source, path = nil)
end
asset_id = rails_asset_id(source)
- if asset_id.blank?
+ if asset_id.empty?
source
else
- source + "?#{asset_id}"
+ "#{source}?#{asset_id}"
end
end
View
1  actionpack/lib/action_view/helpers/date_helper.rb
@@ -923,6 +923,7 @@ def to_datetime_select_tag(options = {}, html_options = {})
private
def datetime_selector(options, html_options)
datetime = value(object) || default_datetime(options)
+ @auto_index ||= nil
options = options.dup
options[:field_name] = @method_name
View
37 actionpack/lib/action_view/helpers/form_helper.rb
@@ -850,7 +850,7 @@ module InstanceTagMethods #:nodoc:
extend ActiveSupport::Concern
include Helpers::CaptureHelper, Context, Helpers::TagHelper, Helpers::FormTagHelper
- attr_reader :method_name, :object_name
+ attr_reader :object, :method_name, :object_name
DEFAULT_FIELD_OPTIONS = { "size" => 30 }
DEFAULT_RADIO_OPTIONS = { }
@@ -859,14 +859,9 @@ module InstanceTagMethods #:nodoc:
def initialize(object_name, method_name, template_object, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@template_object = template_object
- @object = object
- if @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
- if (object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
- @auto_index = object.to_param
- else
- raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
- end
- end
+ @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
+ @object = retrieve_object(object)
+ @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
end
def to_label_tag(text = nil, options = {}, &block)
@@ -990,14 +985,26 @@ def to_content_tag(tag_name, options = {})
content_tag(tag_name, value(object), options)
end
- def object
- @object || @template_object.instance_variable_get("@#{@object_name}")
+ def retrieve_object(object)
+ if object
+ object
+ elsif @template_object.instance_variable_defined?("@#{@object_name}")
+ @template_object.instance_variable_get("@#{@object_name}")
+ end
rescue NameError
- # As @object_name may contain the nested syntax (item[subobject]) we
- # need to fallback to nil.
+ # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.
nil
end
+ def retrieve_autoindex(pre_match)
+ object = self.object || @template_object.instance_variable_get("@#{pre_match}")
+ if object && object.respond_to?(:to_param)
+ object.to_param
+ else
+ raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
+ end
+ end
+
def value(object)
self.class.value(object, @method_name)
end
@@ -1008,7 +1015,7 @@ def value_before_type_cast(object)
module ClassMethods
def value(object, method_name)
- object.send method_name unless object.nil?
+ object.send method_name if object
end
def value_before_type_cast(object, method_name)
@@ -1237,7 +1244,7 @@ def submit(value=nil, options={})
end
def emitted_hidden_id?
- @emitted_hidden_id
+ @emitted_hidden_id ||= nil
end
private
View
11 actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -297,7 +297,6 @@ def time_zone_select(object, method, priority_zones = nil, options = {}, html_op
def options_for_select(container, selected = nil)
return container if String === container
- container = container.to_a if Hash === container
selected, disabled = extract_selected_and_disabled(selected).map do | r |
Array.wrap(r).map(&:to_s)
end
@@ -395,12 +394,12 @@ def options_from_collection_for_select(collection, value_method, text_method, se
# <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
# wrap the output in an appropriate <tt><select></tt> tag.
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
- collection.inject("") do |options_for_select, group|
+ collection.map do |group|
group_label_string = eval("group.#{group_label_method}")
- options_for_select += "<optgroup label=\"#{html_escape(group_label_string)}\">"
- options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key)
- options_for_select += '</optgroup>'
- end.html_safe
+ "<optgroup label=\"#{html_escape(group_label_string)}\">" +
+ options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key) +
+ '</optgroup>'
+ end.join.html_safe
end
# Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
View
2  actionpack/lib/action_view/helpers/text_helper.rb
@@ -365,7 +365,7 @@ def cycle(first_value, *values)
# <% end %>
def current_cycle(name = "default")
cycle = get_cycle(name)
- cycle.current_value unless cycle.nil?
+ cycle.current_value if cycle
end
# Resets a cycle so that it starts from the first element the next time
View
28 actionpack/lib/action_view/helpers/url_helper.rb
@@ -95,7 +95,7 @@ def url_options
# # => javascript:history.back()
def url_for(options = {})
options ||= {}
- url = case options
+ case options
when String
options
when Hash
@@ -106,8 +106,6 @@ def url_for(options = {})
else
polymorphic_path(options)
end
-
- url
end
# Creates a link tag of the given +name+ using a URL created by the set
@@ -586,20 +584,24 @@ def current_page?(options)
private
def convert_options_to_data_attributes(options, html_options)
- html_options = {} if html_options.nil?
- html_options = html_options.stringify_keys
+ if html_options.nil?
+ link_to_remote_options?(options) ? {'data-remote' => 'true'} : {}
+ else
+ html_options = html_options.stringify_keys
+ html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options)
- if (options.is_a?(Hash) && options.key?('remote') && options.delete('remote')) || (html_options.is_a?(Hash) && html_options.key?('remote') && html_options.delete('remote'))
- html_options['data-remote'] = 'true'
- end
+ confirm = html_options.delete('confirm')
+ method = html_options.delete('method')
- confirm = html_options.delete("confirm")
- method, href = html_options.delete("method"), html_options['href']
+ add_confirm_to_attributes!(html_options, confirm) if confirm
+ add_method_to_attributes!(html_options, method) if method
- add_confirm_to_attributes!(html_options, confirm) if confirm
- add_method_to_attributes!(html_options, method) if method
+ html_options
+ end
+ end
- html_options
+ def link_to_remote_options?(options)
+ options.is_a?(Hash) && options.key?('remote') && options.delete('remote')
end
def add_confirm_to_attributes!(html_options, confirm)
View
2  actionpack/lib/action_view/template.rb
@@ -101,6 +101,8 @@ class Template
attr_reader :source, :identifier, :handler, :virtual_path, :formats,
:original_encoding
+ # This finalizer is needed (and exactly with a proc inside another proc)
+ # otherwise templates leak in development.
Finalizer = proc do |method_name, mod|
proc do
mod.module_eval do
View
1  actionpack/lib/action_view/template/error.rb
@@ -52,6 +52,7 @@ class Error < ActionViewError #:nodoc:
def initialize(template, assigns, original_exception)
@template, @assigns, @original_exception = template, assigns.dup, original_exception
+ @sub_templates = nil
@backtrace = original_exception.backtrace
end
View
1  actionpack/lib/action_view/template/resolver.rb
@@ -6,6 +6,7 @@ module ActionView
# = Action View Resolver
class Resolver
def initialize
+ @path = nil
@cached = Hash.new { |h1,k1| h1[k1] =
Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } }
end
View
29 actionpack/lib/action_view/test_case.rb
@@ -20,12 +20,12 @@ def controller_path=(path)
end
def initialize
+ super
self.class.controller_path = ""
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.env.delete('PATH_INFO')
-
@params = {}
end
end
@@ -127,6 +127,7 @@ def response_from_page_or_rjs
def say_no_to_protect_against_forgery!
_helpers.module_eval do
+ remove_method :protect_against_forgery? if method_defined?(:protect_against_forgery?)
def protect_against_forgery?
false
end
@@ -136,8 +137,10 @@ def protect_against_forgery?
def make_test_case_available_to_view!
test_case_instance = self
_helpers.module_eval do
- define_method(:_test_case) { test_case_instance }
- private :_test_case
+ unless private_method_defined?(:_test_case)
+ define_method(:_test_case) { test_case_instance }
+ private :_test_case
+ end
end
end
@@ -153,15 +156,15 @@ def _render_partial(options)
# The instance of ActionView::Base that is used by +render+.
def view
@view ||= begin
- view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
- view.singleton_class.send :include, _helpers
- view.singleton_class.send :include, @controller._routes.url_helpers
- view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
- view.extend(Locals)
- view.locals = self.locals
- view.output_buffer = self.output_buffer
- view
- end
+ view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
+ view.singleton_class.send :include, _helpers
+ view.singleton_class.send :include, @controller._routes.url_helpers
+ view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
+ view.extend(Locals)
+ view.locals = self.locals
+ view.output_buffer = self.output_buffer
+ view
+ end
end
alias_method :_view, :view
@@ -198,7 +201,7 @@ def _routes
def method_missing(selector, *args)
if @controller.respond_to?(:_routes) &&
- @controller._routes.named_routes.helpers.include?(selector)
+ @controller._routes.named_routes.helpers.include?(selector)
@controller.__send__(selector, *args)
else
super
View
8 actionpack/lib/action_view/testing/resolvers.rb
@@ -22,10 +22,10 @@ def query(path, exts, formats)
end
templates = []
- @hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source|
- handler, format = extract_handler_and_format(path, formats)
- templates << Template.new(source, path, handler,
- :virtual_path => path, :format => format)
+ @hash.select { |k,v| k =~ /^#{query}$/ }.each do |_path, source|
+ handler, format = extract_handler_and_format(_path, formats)
+ templates << Template.new(source, _path, handler,
+ :virtual_path => _path, :format => format)
end
templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
View
6 actionpack/test/abstract/callbacks_test.rb
@@ -47,6 +47,7 @@ def aroundz
end
def index
+ @text ||= nil
self.response_body = @text.to_s
end
end
@@ -152,7 +153,7 @@ def setup
test "when :except is specified, an after filter is not triggered on that action" do
result = @controller.process(:index)
- assert_nil @controller.instance_variable_get("@authenticated")
+ assert !@controller.instance_variable_defined?("@authenticated")
end
end
@@ -196,7 +197,7 @@ def setup
test "when :except is specified with an array, an after filter is not triggered on that action" do
result = @controller.process(:index)
- assert_nil @controller.instance_variable_get("@authenticated")
+ assert !@controller.instance_variable_defined?("@authenticated")
end
end
@@ -204,6 +205,7 @@ class ChangedConditions < Callback2
before_filter :first, :only => :index
def not_index
+ @text ||= nil
self.response_body = @text.to_s
end
end
View
2  actionpack/test/abstract/layouts_test.rb
@@ -225,7 +225,7 @@ class TestBase < ActiveSupport::TestCase
end
test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do
- assert_raises(NoMethodError) { WithSymbolAndNoMethod.new.process(:index) }
+ assert_raises(NameError) { WithSymbolAndNoMethod.new.process(:index) }
end
test "when the layout is specified as a symbol and the method returns something besides a string/false/nil, raise an exception" do
View
4 actionpack/test/activerecord/controller_runtime_test.rb
@@ -37,6 +37,6 @@ def test_log_with_active_record
wait
assert_equal 2, @logger.logged(:info).size
- assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1]
+ assert_match(/\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1])
end
-end
+end
View
32 actionpack/test/activerecord/render_partial_with_record_identification_test.rb
@@ -93,38 +93,6 @@ def test_rendering_partial_with_has_one_association
end
end
-class RenderPartialWithRecordIdentificationController < ActionController::Base
- def render_with_has_many_and_belongs_to_association
- @developer = Developer.find(1)
- render :partial => @developer.projects
- end
-
- def render_with_has_many_association
- @topic = Topic.find(1)
- render :partial => @topic.replies
- end
-
- def render_with_has_many_through_association
- @developer = Developer.find(:first)
- render :partial => @developer.topics
- end
-
- def render_with_belongs_to_association
- @reply = Reply.find(1)
- render :partial => @reply.topic
- end
-
- def render_with_record
- @developer = Developer.find(:first)
- render :partial => @developer
- end
-
- def render_with_record_collection
- @developers = Developer.find(:all)
- render :partial => @developers
- end
-end
-
class Game < Struct.new(:name, :id)
extend ActiveModel::Naming
include ActiveModel::Conversion
View
13 actionpack/test/controller/action_pack_assertions_test.rb
@@ -32,6 +32,8 @@ def redirect_to_controller_with_symbol() redirect_to :controller => :elsewhere,
def redirect_to_path() redirect_to '/some/path' end
+ def redirect_invalid_external_route() redirect_to 'ht_tp://www.rubyonrails.org' end
+
def redirect_to_named_route() redirect_to route_one_url end
def redirect_external() redirect_to "http://www.rubyonrails.org"; end
@@ -234,13 +236,13 @@ def test_assert_redirected_to_top_level_named_route_with_same_controller_name_in
def test_template_objects_exist
process :assign_this
- assert !@controller.instance_variable_get(:"@hi")
+ assert !@controller.instance_variable_defined?(:"@hi")
assert @controller.instance_variable_get(:"@howdy")
end
def test_template_objects_missing
process :nothing
- assert_nil @controller.instance_variable_get(:@howdy)
+ assert !@controller.instance_variable_defined?(:@howdy)
end
def test_empty_flash
@@ -314,7 +316,7 @@ def test_client_error_response_code
def test_redirect_url_match
process :redirect_external
assert @response.redirect?
- assert_match /rubyonrails/, @response.redirect_url
+ assert_match(/rubyonrails/, @response.redirect_url)
assert !/perloffrails/.match(@response.redirect_url)
end