aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller.rb1
-rw-r--r--actionpack/lib/abstract_controller/railties/routes_helpers.rb18
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb1
-rw-r--r--actionpack/lib/abstract_controller/url_for.rb28
-rw-r--r--actionpack/lib/action_controller/base.rb7
-rw-r--r--actionpack/lib/action_controller/metal.rb6
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb6
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb24
-rw-r--r--actionpack/lib/action_controller/railtie.rb9
-rw-r--r--actionpack/lib/action_controller/railties/paths.rb20
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb64
-rw-r--r--actionpack/lib/action_dispatch/routing.rb1
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb38
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb28
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb76
-rw-r--r--actionpack/lib/action_dispatch/routing/routes_proxy.rb35
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb12
-rw-r--r--actionpack/lib/action_dispatch/testing/test_request.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb10
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb4
22 files changed, 319 insertions, 75 deletions
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index f8fc79936f..cc5878c88e 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -24,4 +24,5 @@ module AbstractController
autoload :Translation
autoload :AssetPaths
autoload :ViewPaths
+ autoload :UrlFor
end
diff --git a/actionpack/lib/abstract_controller/railties/routes_helpers.rb b/actionpack/lib/abstract_controller/railties/routes_helpers.rb
new file mode 100644
index 0000000000..dec1e9d6d9
--- /dev/null
+++ b/actionpack/lib/abstract_controller/railties/routes_helpers.rb
@@ -0,0 +1,18 @@
+module AbstractController
+ module Railties
+ module RoutesHelpers
+ def self.with(routes)
+ Module.new do
+ define_method(:inherited) do |klass|
+ super(klass)
+ if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
+ klass.send(:include, namespace._railtie.routes.url_helpers)
+ else
+ klass.send(:include, routes.url_helpers)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index b81d5954eb..5d9b35d297 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -52,6 +52,7 @@ module AbstractController
if controller.respond_to?(:_routes)
include controller._routes.url_helpers
+ include controller._routes.mounted_helpers
end
# TODO: Fix RJS to not require this
diff --git a/actionpack/lib/abstract_controller/url_for.rb b/actionpack/lib/abstract_controller/url_for.rb
new file mode 100644
index 0000000000..2e9de22ecd
--- /dev/null
+++ b/actionpack/lib/abstract_controller/url_for.rb
@@ -0,0 +1,28 @@
+module AbstractController
+ module UrlFor
+ extend ActiveSupport::Concern
+
+ include ActionDispatch::Routing::UrlFor
+
+ def _routes
+ raise "In order to use #url_for, you must include routing helpers explicitly. " \
+ "For instance, `include Rails.application.routes.url_helpers"
+ end
+
+ module ClassMethods
+ def _routes
+ nil
+ end
+
+ def action_methods
+ @action_methods ||= begin
+ if _routes
+ super - _routes.named_routes.helper_names
+ else
+ super
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 7a1464c2aa..b37bc02127 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -221,11 +221,6 @@ module ActionController
# Rails 2.x compatibility
include ActionController::Compatibility
- def self.inherited(klass)
- super
- klass.helper :all if klass.superclass == ActionController::Base
- end
-
ActiveSupport.run_load_hooks(:action_controller, self)
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 96ac138ba3..def28a0054 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -52,7 +52,11 @@ module ActionController
class Metal < AbstractController::Base
abstract!
- attr_internal :env
+ attr_internal_writer :env
+
+ def env
+ @_env ||= {}
+ end
# Returns the last part of the controller's name, underscored, without the ending
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 4b6897c5dd..c5d7842db3 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -101,8 +101,12 @@ module ActionController
# Extract helper names from files in <tt>app/helpers/**/*_helper.rb</tt>
def all_application_helpers
+ all_helpers_from_path(helpers_path)
+ end
+
+ def all_helpers_from_path(path)
helpers = []
- Array.wrap(helpers_path).each do |path|
+ 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
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index a51fc5b8e4..85c6b0a9b5 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -2,27 +2,19 @@ module ActionController
module UrlFor
extend ActiveSupport::Concern
- include ActionDispatch::Routing::UrlFor
+ include AbstractController::UrlFor
def url_options
- super.reverse_merge(
+ options = {}
+ if _routes.equal?(env["action_dispatch.routes"])
+ options[:script_name] = request.script_name.dup
+ end
+
+ super.merge(options).reverse_merge(
:host => request.host_with_port,
:protocol => request.protocol,
:_path_segments => request.symbolized_path_parameters
- ).merge(:script_name => request.script_name)
- end
-
- def _routes
- raise "In order to use #url_for, you must include routing helpers explicitly. " \
- "For instance, `include Rails.application.routes.url_helpers"
- end
-
- module ClassMethods
- def action_methods
- @action_methods ||= begin
- super - _routes.named_routes.helper_names
- end
- end
+ )
end
end
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index cd2dfafbe6..0cb4041855 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -4,6 +4,8 @@ require "action_dispatch/railtie"
require "action_view/railtie"
require "active_support/deprecation/proxy_wrappers"
require "active_support/deprecation"
+require "abstract_controller/railties/routes_helpers"
+require "action_controller/railties/paths"
module ActionController
class Railtie < Rails::Railtie
@@ -47,10 +49,11 @@ module ActionController
options.javascripts_dir ||= paths.public.javascripts.to_a.first
options.stylesheets_dir ||= paths.public.stylesheets.to_a.first
options.page_cache_directory ||= paths.public.to_a.first
- options.helpers_path ||= paths.app.helpers.to_a
ActiveSupport.on_load(:action_controller) do
- include app.routes.url_helpers
+ include app.routes.mounted_helpers(:app)
+ extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
+ extend ::ActionController::Railties::Paths.with(app)
options.each { |k,v| send("#{k}=", v) }
end
end
@@ -63,4 +66,4 @@ module ActionController
ActionController::Routing::Routes = proxy
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/railties/paths.rb b/actionpack/lib/action_controller/railties/paths.rb
new file mode 100644
index 0000000000..fa71d55946
--- /dev/null
+++ b/actionpack/lib/action_controller/railties/paths.rb
@@ -0,0 +1,20 @@
+module ActionController
+ module Railties
+ module Paths
+ def self.with(app)
+ Module.new do
+ define_method(:inherited) do |klass|
+ super(klass)
+ if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
+ klass.helpers_path = namespace._railtie.config.paths.app.helpers.to_a
+ else
+ klass.helpers_path = app.config.helpers_paths
+ end
+
+ klass.helper :all if klass.superclass == ActionController::Base
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index 5a029a60d1..6f243574e4 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -1,4 +1,5 @@
require "active_support/inflector/methods"
+require "active_support/dependencies"
module ActionDispatch
class MiddlewareStack < Array
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index d7e88a54e4..581cadbeb4 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -1,12 +1,47 @@
require 'rack/utils'
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_root = Regexp.compile(/^#{Regexp.escape(root)}/)
+ @file_server = ::Rack::File.new(root)
+ end
+
+ def match?(path)
+ path = path.dup
+ if @compiled_at.blank? || path.sub!(@compiled_at, '')
+ full_path = File.join(@root, ::Rack::Utils.unescape(path))
+ paths = "#{full_path}#{ext}"
+
+ matches = Dir[paths]
+ match = matches.detect { |m| File.file?(m) }
+ if match
+ match.sub!(@compiled_root, '')
+ match
+ end
+ end
+ end
+
+ def call(env)
+ @file_server.call(env)
+ end
+
+ def ext
+ @ext ||= begin
+ ext = ::ActionController::Base.page_cache_extension
+ "{,#{ext},/index#{ext}}"
+ end
+ end
+ end
+
class Static
FILE_METHODS = %w(GET HEAD).freeze
- def initialize(app, root)
+ def initialize(app, roots)
@app = app
- @file_server = ::Rack::File.new(root)
+ @file_handlers = create_file_handlers(roots)
end
def call(env)
@@ -14,15 +49,10 @@ module ActionDispatch
method = env['REQUEST_METHOD']
if FILE_METHODS.include?(method)
- if file_exist?(path)
- return @file_server.call(env)
- else
- cached_path = directory_exist?(path) ? "#{path}/index" : path
- cached_path += ::ActionController::Base.page_cache_extension
-
- if file_exist?(cached_path)
- env['PATH_INFO'] = cached_path
- return @file_server.call(env)
+ @file_handlers.each do |file_handler|
+ if match = file_handler.match?(path)
+ env["PATH_INFO"] = match
+ return file_handler.call(env)
end
end
end
@@ -31,14 +61,12 @@ module ActionDispatch
end
private
- def file_exist?(path)
- full_path = File.join(@file_server.root, ::Rack::Utils.unescape(path))
- File.file?(full_path) && File.readable?(full_path)
- end
+ def create_file_handlers(roots)
+ roots = { '' => roots } unless roots.is_a?(Hash)
- def directory_exist?(path)
- full_path = File.join(@file_server.root, ::Rack::Utils.unescape(path))
- File.directory?(full_path) && File.readable?(full_path)
+ roots.map do |at, root|
+ FileHandler.new(at, root) if File.exist?(root)
+ end.compact
end
end
end
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 0b9689dc88..b2b0f4c08e 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -268,6 +268,7 @@ module ActionDispatch
autoload :Mapper, 'action_dispatch/routing/mapper'
autoload :Route, 'action_dispatch/routing/route'
autoload :RouteSet, 'action_dispatch/routing/route_set'
+ autoload :RoutesProxy, 'action_dispatch/routing/routes_proxy'
autoload :UrlFor, 'action_dispatch/routing/url_for'
autoload :PolymorphicRoutes, 'action_dispatch/routing/polymorphic_routes'
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index a2570cb877..900900ee24 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -261,7 +261,11 @@ module ActionDispatch
raise "A rack application must be specified" unless path
+ options[:as] ||= app_name(app)
+
match(path, options.merge(:to => app, :anchor => false, :format => false))
+
+ define_generate_prefix(app, options[:as])
self
end
@@ -269,6 +273,40 @@ module ActionDispatch
@set.default_url_options = options
end
alias_method :default_url_options, :default_url_options=
+
+ def with_default_scope(scope, &block)
+ scope(scope) do
+ instance_exec(&block)
+ end
+ end
+
+ private
+ def app_name(app)
+ return unless app.respond_to?(:routes)
+
+ if app.respond_to?(:railtie_name)
+ app.railtie_name
+ else
+ class_name = app.class.is_a?(Class) ? app.name : app.class.name
+ ActiveSupport::Inflector.underscore(class_name).gsub("/", "_")
+ end
+ end
+
+ def define_generate_prefix(app, name)
+ return unless app.respond_to?(:routes)
+
+ _route = @set.named_routes.routes[name.to_sym]
+ _routes = @set
+ app.routes.define_mounted_helper(name)
+ app.routes.class_eval do
+ define_method :_generate_prefix do |options|
+ prefix_options = options.slice(*_route.segment_keys)
+ # we must actually delete prefix segment keys to avoid passing them to next url_for
+ _route.segment_keys.each { |k| options.delete(k) }
+ _routes.url_helpers.send("#{name}_path", prefix_options)
+ end
+ end
+ end
end
module HttpHelpers
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index fb2118a8d7..02ba5236ee 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -42,6 +42,18 @@ module ActionDispatch
#
# edit_polymorphic_path(@post) # => "/posts/1/edit"
# polymorphic_path(@post, :format => :pdf) # => "/posts/1.pdf"
+ #
+ # == Using with mounted engines
+ #
+ # If you use mounted engine, there is a possibility that you will need to use
+ # polymorphic_url pointing at engine's routes. To do that, just pass proxy used
+ # to reach engine's routes as a first argument:
+ #
+ # For example:
+ #
+ # polymorphic_url([blog, @post]) # it will call blog.post_path(@post)
+ # form_for([blog, @post]) # => "/blog/posts/1
+ #
module PolymorphicRoutes
# Constructs a call to a named RESTful route for the given record and returns the
# resulting URL string. For example:
@@ -78,6 +90,9 @@ module ActionDispatch
def polymorphic_url(record_or_hash_or_array, options = {})
if record_or_hash_or_array.kind_of?(Array)
record_or_hash_or_array = record_or_hash_or_array.compact
+ if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
+ proxy = record_or_hash_or_array.shift
+ end
record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1
end
@@ -111,7 +126,14 @@ module ActionDispatch
args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
end
- send(named_route, *args)
+ if proxy
+ proxy.send(named_route, *args)
+ else
+ # we need to use url_for, because polymorphic_url can be used in context of other than
+ # current routes (e.g. engine's routes). As named routes from engine are not included
+ # calling engine's named route directly would fail.
+ url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args)
+ end
end
# Returns the path component of a URL for the given record. It uses
@@ -155,7 +177,7 @@ module ActionDispatch
if parent.is_a?(Symbol) || parent.is_a?(String)
parent
else
- ActiveModel::Naming.plural(parent).singularize
+ ActiveModel::Naming.route_key(parent).singularize
end
end
end
@@ -163,7 +185,7 @@ module ActionDispatch
if record.is_a?(Symbol) || record.is_a?(String)
route << record
else
- route << ActiveModel::Naming.plural(record)
+ route << ActiveModel::Naming.route_key(record)
route = [route.join("_").singularize] if inflection == :singular
route << "index" if ActiveModel::Naming.uncountable?(record) && inflection == :plural
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index b531cc1a8e..107e44287d 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -158,10 +158,17 @@ module ActionDispatch
# We use module_eval to avoid leaks
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
- def #{selector}(options = nil) # def hash_for_users_url(options = nil)
- options ? #{options.inspect}.merge(options) : #{options.inspect} # options ? {:only_path=>false}.merge(options) : {:only_path=>false}
- end # end
- protected :#{selector} # protected :hash_for_users_url
+ def #{selector}(*args)
+ options = args.extract_options!
+
+ if args.any?
+ options[:_positional_args] = args
+ options[:_positional_keys] = #{route.segment_keys.inspect}
+ end
+
+ options ? #{options.inspect}.merge(options) : #{options.inspect}
+ end
+ protected :#{selector}
END_EVAL
helpers << selector
end
@@ -185,21 +192,14 @@ module ActionDispatch
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
def #{selector}(*args)
- options = #{hash_access_method}(args.extract_options!)
-
- if args.any?
- options[:_positional_args] = args
- options[:_positional_keys] = #{route.segment_keys.inspect}
- end
-
- url_for(options)
+ url_for(#{hash_access_method}(*args))
end
END_EVAL
helpers << selector
end
end
- attr_accessor :set, :routes, :named_routes
+ attr_accessor :set, :routes, :named_routes, :default_scope
attr_accessor :disable_clear_and_finalize, :resources_path_names
attr_accessor :default_url_options, :request_class, :valid_conditions
@@ -230,7 +230,11 @@ module ActionDispatch
if block.arity == 1
mapper.instance_exec(DeprecatedMapper.new(self), &block)
else
- mapper.instance_exec(&block)
+ if default_scope
+ mapper.with_default_scope(default_scope, &block)
+ else
+ mapper.instance_exec(&block)
+ end
end
finalize! unless @disable_clear_and_finalize
@@ -261,6 +265,31 @@ module ActionDispatch
named_routes.install(destinations, regenerate_code)
end
+ module MountedHelpers
+ end
+
+ def mounted_helpers(name = nil)
+ define_mounted_helper(name) if name
+ MountedHelpers
+ end
+
+ def define_mounted_helper(name)
+ return if MountedHelpers.method_defined?(name)
+
+ routes = self
+ MountedHelpers.class_eval do
+ define_method "_#{name}" do
+ RoutesProxy.new(routes, self._routes_context)
+ end
+ end
+
+ MountedHelpers.class_eval <<-RUBY
+ def #{name}
+ @#{name} ||= _#{name}
+ end
+ RUBY
+ end
+
def url_helpers
@url_helpers ||= begin
routes = self
@@ -283,7 +312,7 @@ module ActionDispatch
singleton_class.send(:define_method, :_routes) { routes }
end
- define_method(:_routes) { routes }
+ define_method(:_routes) { @_routes || routes }
end
helpers
@@ -303,10 +332,9 @@ module ActionDispatch
end
class Generator #:nodoc:
- attr_reader :options, :recall, :set, :script_name, :named_route
+ attr_reader :options, :recall, :set, :named_route
def initialize(options, recall, set, extras = false)
- @script_name = options.delete(:script_name)
@named_route = options.delete(:use_route)
@options = options.dup
@recall = recall.dup
@@ -401,7 +429,7 @@ module ActionDispatch
return [path, params.keys] if @extras
path << "?#{params.to_query}" if params.any?
- "#{script_name}#{path}"
+ path
rescue Rack::Mount::RoutingError
raise_routing_error
end
@@ -453,7 +481,11 @@ module ActionDispatch
Generator.new(options, recall, self, extras).generate
end
- RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash]
+ RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :script_name]
+
+ def _generate_prefix(options = {})
+ nil
+ end
def url_for(options)
finalize!
@@ -464,7 +496,6 @@ module ActionDispatch
rewritten_url = ""
path_segments = options.delete(:_path_segments)
-
unless options[:only_path]
rewritten_url << (options[:protocol] || "http")
rewritten_url << "://" unless rewritten_url.match("://")
@@ -476,9 +507,12 @@ module ActionDispatch
rewritten_url << ":#{options.delete(:port)}" if options.key?(:port)
end
+ script_name = options.delete(:script_name)
+ path = (script_name.blank? ? _generate_prefix(options) : script_name).to_s
+
path_options = options.except(*RESERVED_OPTIONS)
path_options = yield(path_options) if block_given?
- path = generate(path_options, path_segments || {})
+ path << generate(path_options, path_segments || {})
# ROUTES TODO: This can be called directly, so script_name should probably be set in the routes
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
diff --git a/actionpack/lib/action_dispatch/routing/routes_proxy.rb b/actionpack/lib/action_dispatch/routing/routes_proxy.rb
new file mode 100644
index 0000000000..f7d5f6397d
--- /dev/null
+++ b/actionpack/lib/action_dispatch/routing/routes_proxy.rb
@@ -0,0 +1,35 @@
+module ActionDispatch
+ module Routing
+ class RoutesProxy #:nodoc:
+ include ActionDispatch::Routing::UrlFor
+
+ attr_accessor :scope, :routes
+ alias :_routes :routes
+
+ def initialize(routes, scope)
+ @routes, @scope = routes, scope
+ end
+
+ def url_options
+ scope.send(:_with_routes, routes) do
+ scope.url_options
+ end
+ end
+
+ def method_missing(method, *args)
+ if routes.url_helpers.respond_to?(method)
+ self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def #{method}(*args)
+ options = args.extract_options!
+ args << url_options.merge((options || {}).symbolize_keys)
+ routes.url_helpers.#{method}(*args)
+ end
+ RUBY
+ send(method, *args)
+ else
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index 28ec830fe8..e836cf7c8e 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -133,6 +133,18 @@ module ActionDispatch
polymorphic_url(options)
end
end
+
+ protected
+ def _with_routes(routes)
+ old_routes, @_routes = @_routes, routes
+ yield
+ ensure
+ @_routes = old_routes
+ end
+
+ def _routes_context
+ self
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb
index b3e67f6e36..c587a36930 100644
--- a/actionpack/lib/action_dispatch/testing/test_request.rb
+++ b/actionpack/lib/action_dispatch/testing/test_request.rb
@@ -10,7 +10,7 @@ module ActionDispatch
end
def initialize(env = {})
- env = Rails.application.env_defaults.merge(env) if defined?(Rails.application)
+ env = Rails.application.env_config.merge(env) if defined?(Rails.application)
super(DEFAULT_ENV.merge(env))
self.host = 'test.host'
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index a3c43d3e93..3329a8b368 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -727,6 +727,9 @@ module ActionView
source += ".#{ext}" if rewrite_extension?(source, dir, 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)
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 94dc25eb85..43dbedc448 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -304,12 +304,12 @@ module ActionView
object_name = record_or_name_or_array
when Array
object = record_or_name_or_array.last
- object_name = options[:as] || ActiveModel::Naming.singular(object)
+ object_name = options[:as] || ActiveModel::Naming.param_key(object)
apply_form_for_options!(record_or_name_or_array, options)
args.unshift object
else
object = record_or_name_or_array
- object_name = options[:as] || ActiveModel::Naming.singular(object)
+ object_name = options[:as] || ActiveModel::Naming.param_key(object)
apply_form_for_options!([object], options)
args.unshift object
end
@@ -539,7 +539,7 @@ module ActionView
object_name = record
else
object = record
- object_name = ActiveModel::Naming.singular(object)
+ object_name = ActiveModel::Naming.param_key(object)
end
builder = options[:builder] || ActionView::Base.default_form_builder
@@ -1168,11 +1168,11 @@ module ActionView
end
when Array
object = record_or_name_or_array.last
- name = "#{object_name}#{index}[#{ActiveModel::Naming.singular(object)}]"
+ name = "#{object_name}#{index}[#{ActiveModel::Naming.param_key(object)}]"
args.unshift(object)
else
object = record_or_name_or_array
- name = "#{object_name}#{index}[#{ActiveModel::Naming.singular(object)}]"
+ name = "#{object_name}#{index}[#{ActiveModel::Naming.param_key(object)}]"
args.unshift(object)
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index b8df2d9a69..555be6ed2b 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -22,6 +22,10 @@ module ActionView
include ActionDispatch::Routing::UrlFor
include TagHelper
+ def _routes_context
+ controller
+ end
+
# Need to map default url options to controller one.
# def default_url_options(*args) #:nodoc:
# controller.send(:default_url_options, *args)