aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2009-11-22 10:31:47 -0800
committerJeremy Kemper <jeremy@bitsweat.net>2009-11-22 10:31:47 -0800
commite68bc3f14ea93eabdd4274e66071b65debb5a0a8 (patch)
tree223c11f38dac1217d8e7e3cd427fdf6018975a9d /actionpack/lib
parent3cb46b40a0df1a1f4912625cc2be40b3d630f1f3 (diff)
parente1935e3c0c35f8f1196239e2b1213c4436049fa5 (diff)
downloadrails-e68bc3f14ea93eabdd4274e66071b65debb5a0a8.tar.gz
rails-e68bc3f14ea93eabdd4274e66071b65debb5a0a8.tar.bz2
rails-e68bc3f14ea93eabdd4274e66071b65debb5a0a8.zip
Merge commit 'origin/master' into mail
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb2
-rw-r--r--actionpack/lib/abstract_controller/rendering_controller.rb6
-rw-r--r--actionpack/lib/action_controller/caching.rb1
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb5
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb44
-rw-r--r--actionpack/lib/action_controller/metal/streaming.rb2
-rw-r--r--actionpack/lib/action_controller/translation.rb4
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb6
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb30
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb67
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions.rb19
-rw-r--r--actionpack/lib/action_view/erb/util.rb1
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb13
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb1
16 files changed, 111 insertions, 98 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 1616f8030a..c71cef42b2 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -100,7 +100,7 @@ module AbstractController
# name, return that string. Otherwise, use the superclass'
# layout (which might also be implied)
def _write_layout_method
- case @_layout
+ case defined?(@_layout) ? @_layout : nil
when String
self.class_eval %{def _layout(details) #{@_layout.inspect} end}
when Symbol
diff --git a/actionpack/lib/abstract_controller/rendering_controller.rb b/actionpack/lib/abstract_controller/rendering_controller.rb
index 0aae2b18e9..7054b9cf26 100644
--- a/actionpack/lib/abstract_controller/rendering_controller.rb
+++ b/actionpack/lib/abstract_controller/rendering_controller.rb
@@ -12,6 +12,12 @@ module AbstractController
self._view_paths ||= ActionView::PathSet.new
end
+ # Initialize controller with nil formats.
+ def initialize(*) #:nodoc:
+ @_formats = nil
+ super
+ end
+
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb
index 083d6328af..3caf759032 100644
--- a/actionpack/lib/action_controller/caching.rb
+++ b/actionpack/lib/action_controller/caching.rb
@@ -26,6 +26,7 @@ module ActionController #:nodoc:
# config.action_controller.cache_store = :file_store, "/path/to/cache/directory"
# config.action_controller.cache_store = :drb_store, "druby://localhost:9192"
# config.action_controller.cache_store = :mem_cache_store, "localhost"
+ # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new("localhost:11211")
# config.action_controller.cache_store = MyOwnStore.new("parameter")
module Caching
extend ActiveSupport::Concern
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 113c20a758..173df79ee7 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -101,6 +101,11 @@ module ActionController #:nodoc:
session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end
+ # The form's authenticity parameter. Override to provide your own.
+ def form_authenticity_param
+ params[request_forgery_protection_token]
+ end
+
def protect_against_forgery?
allow_forgery_protection
end
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index c6e847ba0f..e8e88e7479 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -14,12 +14,11 @@ module ActionController #:nodoc:
#
# When a request comes, for example with format :xml, three steps happen:
#
- # 1) respond_with searches for a template at people/index.xml;
+ # 1) responder searches for a template at people/index.xml;
#
- # 2) if the template is not available, it will create a responder, passing
- # the controller and the resource and invoke :to_xml on it;
+ # 2) if the template is not available, it will invoke :to_xml in the given resource;
#
- # 3) if the responder does not respond_to :to_xml, call to_format on it.
+ # 3) if the responder does not respond_to :to_xml, call :to_format on it.
#
# === Builtin HTTP verb semantics
#
@@ -88,14 +87,16 @@ module ActionController #:nodoc:
@resource = resources.is_a?(Array) ? resources.last : resources
@resources = resources
@options = options
+ @action = options.delete(:action)
@default_response = options.delete(:default_response)
end
delegate :head, :render, :redirect_to, :to => :controller
delegate :get?, :post?, :put?, :delete?, :to => :request
- # Undefine :to_json since it's defined on Object
+ # 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)
# Initializes a new responder an invoke the proper format. If the format is
# not defined, call to_format.
@@ -111,14 +112,8 @@ module ActionController #:nodoc:
#
def to_html
default_render
- rescue ActionView::MissingTemplate
- if get?
- raise
- elsif has_errors?
- render :action => default_action
- else
- redirect_to resource_location
- end
+ rescue ActionView::MissingTemplate => e
+ navigation_behavior(e)
end
# All others formats follow the procedure below. First we try to render a
@@ -127,9 +122,26 @@ module ActionController #:nodoc:
#
def to_format
default_render
- rescue ActionView::MissingTemplate
+ rescue ActionView::MissingTemplate => e
raise unless resourceful?
+ api_behavior(e)
+ end
+ protected
+
+ # This is the common behavior for "navigation" requests, like :html, :iphone and so forth.
+ def navigation_behavior(error)
+ if get?
+ raise error
+ elsif has_errors?
+ render :action => default_action
+ else
+ redirect_to resource_location
+ end
+ end
+
+ # This is the common behavior for "API" requests, like :xml and :json.
+ def api_behavior(error)
if get?
display resource
elsif has_errors?
@@ -141,8 +153,6 @@ module ActionController #:nodoc:
end
end
- protected
-
# Checks whether the resource responds to the current format or not.
#
def resourceful?
@@ -194,7 +204,7 @@ module ActionController #:nodoc:
# the verb is post.
#
def default_action
- request.post? ? :new : :edit
+ @action || (request.post? ? :new : :edit)
end
end
end
diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb
index 4761763a26..43c661bef4 100644
--- a/actionpack/lib/action_controller/metal/streaming.rb
+++ b/actionpack/lib/action_controller/metal/streaming.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/string/bytesize'
-
module ActionController #:nodoc:
# Methods for sending arbitrary data and for streaming files to the browser,
# instead of rendering.
diff --git a/actionpack/lib/action_controller/translation.rb b/actionpack/lib/action_controller/translation.rb
index 9bb63cdb15..65e9eddb0a 100644
--- a/actionpack/lib/action_controller/translation.rb
+++ b/actionpack/lib/action_controller/translation.rb
@@ -1,12 +1,12 @@
module ActionController
module Translation
def translate(*args)
- I18n.translate *args
+ I18n.translate(*args)
end
alias :t :translate
def localize(*args)
- I18n.localize *args
+ I18n.localize(*args)
end
alias :l :localize
end
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 75be2cc260..6a52854961 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -5,7 +5,7 @@ require 'strscan'
require 'active_support/memoizable'
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/hash/indifferent_access'
-require 'active_support/core_ext/object/tap'
+require 'active_support/core_ext/string/access'
module ActionDispatch
class Request < Rack::Request
@@ -166,7 +166,7 @@ module ActionDispatch
@env["action_dispatch.request.formats"] ||=
if parameters[:format]
- [Mime[parameters[:format]]]
+ Array.wrap(Mime[parameters[:format]])
elsif xhr? || (accept && !accept.include?(?,))
accepts
else
@@ -489,7 +489,7 @@ EOM
def self.extended(object)
object.class_eval do
attr_accessor :original_path, :content_type
- alias_method :local_path, :path
+ alias_method :local_path, :path if method_defined?(:path)
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index 4f71ea6165..3b27309f58 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -1,3 +1,5 @@
+require "active_support/inflector/methods"
+
module ActionDispatch
class MiddlewareStack < Array
class Middleware
@@ -32,7 +34,7 @@ module ActionDispatch
elsif @klass.respond_to?(:call)
@klass.call
else
- @klass.to_s.constantize
+ ActiveSupport::Inflector.constantize(@klass.to_s)
end
end
@@ -53,7 +55,7 @@ module ActionDispatch
when Class
klass == middleware
else
- klass == middleware.to_s.constantize
+ klass == ActiveSupport::Inflector.constantize(middleware.to_s)
end
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index ebfb4c9be2..6e112c9b54 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -52,30 +52,38 @@ module ActionDispatch
resource = resources.pop
+ plural = resource.to_s
+ singular = plural.singularize
+
if @scope[:scope_level] == :resources
- member do
- resources(resource, options, &block)
+ parent_resource = @scope[:scope_level_options][:name]
+ with_scope_level(:member) do
+ scope(":#{parent_resource}_id", :name_prefix => parent_resource) do
+ resources(resource, options, &block)
+ end
end
return self
end
- plural = resource.to_s
- singular = plural.singularize
+ if @scope[:options] && (prefix = @scope[:options][:name_prefix])
+ plural = "#{prefix}_#{plural}"
+ singular = "#{prefix}_#{singular}"
+ end
controller(resource) do
namespace(resource) do
- with_scope_level(:resources) do
+ with_scope_level(:resources, :name => singular) do
yield if block_given?
member do
- get "", :to => :show, :as => "#{singular}"
+ get "", :to => :show, :as => singular
put "", :to => :update
delete "", :to => :destroy
get "edit", :to => :edit, :as => "edit_#{singular}"
end
collection do
- get "", :to => :index, :as => "#{plural}"
+ get "", :to => :index, :as => plural
post "", :to => :create
get "new", :to => :new, :as => "new_#{singular}"
end
@@ -127,11 +135,13 @@ module ActionDispatch
end
private
- def with_scope_level(kind)
+ def with_scope_level(kind, options = {})
old, @scope[:scope_level] = @scope[:scope_level], kind
+ old_options, @scope[:scope_level_options] = @scope[:scope_level_options], options
yield
ensure
@scope[:scope_level] = old
+ @scope[:scope_level_options] = old_options
end
end
@@ -195,9 +205,9 @@ module ActionDispatch
@constraints.each { |constraint|
if constraint.respond_to?(:matches?) && !constraint.matches?(req)
- return Rack::Mount::Const::EXPECTATION_FAILED_RESPONSE
+ return [417, {}, []]
elsif constraint.respond_to?(:call) && !constraint.call(req)
- return Rack::Mount::Const::EXPECTATION_FAILED_RESPONSE
+ return [417, {}, []]
end
}
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 28e5b806da..c15aaceb5b 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -5,7 +5,7 @@ module ActionDispatch
module Routing
class RouteSet #:nodoc:
NotFound = lambda { |env|
- raise ActionController::RoutingError, "No route matches #{env[::Rack::Mount::Const::PATH_INFO].inspect} with #{env.inspect}"
+ raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect} with #{env.inspect}"
}
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
@@ -372,7 +372,17 @@ module ActionDispatch
end
recall[:action] = options.delete(:action) if options[:action] == 'index'
- path = _uri(named_route, options, recall)
+ parameterize = lambda { |name, value|
+ if name == :controller
+ value
+ elsif value.is_a?(Array)
+ value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
+ else
+ Rack::Mount::Utils.escape_uri(value.to_param)
+ end
+ }
+
+ path = @set.url(named_route, options, recall, :parameterize => parameterize)
if path && method == :generate_extras
uri = URI(path)
extras = uri.query ?
@@ -439,59 +449,6 @@ module ActionDispatch
def extract_request_environment(request)
{ :method => request.method }
end
-
- private
- def _uri(named_route, params, recall)
- params = URISegment.wrap_values(params)
- recall = URISegment.wrap_values(recall)
-
- unless result = @set.generate(:path_info, named_route, params, recall)
- return
- end
-
- uri, params = result
- params.each do |k, v|
- if v._value
- params[k] = v._value
- else
- params.delete(k)
- end
- end
-
- uri << "?#{Rack::Mount::Utils.build_nested_query(params)}" if uri && params.any?
- uri
- end
-
- class URISegment < Struct.new(:_value, :_escape)
- EXCLUDED = [:controller]
-
- def self.wrap_values(hash)
- hash.inject({}) { |h, (k, v)|
- h[k] = new(v, !EXCLUDED.include?(k.to_sym))
- h
- }
- end
-
- extend Forwardable
- def_delegators :_value, :==, :eql?, :hash
-
- def to_param
- @to_param ||= begin
- if _value.is_a?(Array)
- _value.map { |v| _escaped(v) }.join('/')
- else
- _escaped(_value)
- end
- end
- end
- alias_method :to_s, :to_param
-
- private
- def _escaped(value)
- v = value.respond_to?(:to_param) ? value.to_param : value
- _escape ? Rack::Mount::Utils.escape_uri(v) : v.to_s
- end
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions.rb b/actionpack/lib/action_dispatch/testing/assertions.rb
index 96f08f2355..0e4a92048f 100644
--- a/actionpack/lib/action_dispatch/testing/assertions.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions.rb
@@ -1,8 +1,21 @@
module ActionDispatch
module Assertions
- %w(response selector tag dom routing model).each do |kind|
- require "action_dispatch/testing/assertions/#{kind}"
- include const_get("#{kind.camelize}Assertions")
+ autoload :DomAssertions, 'action_dispatch/testing/assertions/dom'
+ autoload :ModelAssertions, 'action_dispatch/testing/assertions/model'
+ autoload :ResponseAssertions, 'action_dispatch/testing/assertions/response'
+ autoload :RoutingAssertions, 'action_dispatch/testing/assertions/routing'
+ autoload :SelectorAssertions, 'action_dispatch/testing/assertions/selector'
+ autoload :TagAssertions, 'action_dispatch/testing/assertions/tag'
+
+ extend ActiveSupport::Concern
+
+ included do
+ include DomAssertions
+ include ModelAssertions
+ include ResponseAssertions
+ include RoutingAssertions
+ include SelectorAssertions
+ include TagAssertions
end
end
end
diff --git a/actionpack/lib/action_view/erb/util.rb b/actionpack/lib/action_view/erb/util.rb
index f767a5e27e..aef859b3ac 100644
--- a/actionpack/lib/action_view/erb/util.rb
+++ b/actionpack/lib/action_view/erb/util.rb
@@ -23,6 +23,7 @@ class ERB
end
end
+ undef :h
alias h html_escape
module_function :html_escape
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index c46b39fc23..d0c66eda60 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -963,7 +963,7 @@ module ActionView
end
end
- (field_helpers - %w(label check_box radio_button fields_for)).each do |selector|
+ (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector|
src = <<-end_src
def #{selector}(method, options = {}) # def text_field(method, options = {})
@template.send( # @template.send(
@@ -1022,6 +1022,11 @@ module ActionView
def radio_button(method, tag_value, options = {})
@template.radio_button(@object_name, method, tag_value, objectify_options(options))
end
+
+ def hidden_field(method, options = {})
+ @emitted_hidden_id = true if method == :id
+ @template.hidden_field(@object_name, method, objectify_options(options))
+ end
def error_message_on(method, *args)
@template.error_message_on(@object, method, *args)
@@ -1035,6 +1040,10 @@ module ActionView
@template.submit_tag(value, options.reverse_merge(:id => "#{object_name}_submit"))
end
+ def emitted_hidden_id?
+ @emitted_hidden_id
+ end
+
private
def objectify_options(options)
@default_options.merge(options.merge(:object => @object))
@@ -1069,8 +1078,8 @@ module ActionView
@template.fields_for(name, object, *args, &block)
else
@template.fields_for(name, object, *args) do |builder|
- @template.concat builder.hidden_field(:id)
block.call(builder)
+ @template.concat builder.hidden_field(:id) unless builder.emitted_hidden_id?
end
end
end
diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb
index 4aed10f640..564f12c955 100644
--- a/actionpack/lib/action_view/helpers/translation_helper.rb
+++ b/actionpack/lib/action_view/helpers/translation_helper.rb
@@ -21,7 +21,7 @@ module ActionView
# Delegates to I18n.localize with no additional functionality.
def localize(*args)
- I18n.localize *args
+ I18n.localize(*args)
end
alias :l :localize
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 8beda24aba..86bbad822d 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -120,6 +120,7 @@ module ActionView
def _view
view = ActionView::Base.new(ActionController::Base.view_paths, _assigns, @controller)
view.class.send :include, _helpers
+ view.output_buffer = self.output_buffer
view
end