diff options
author | José Valim <jose.valim@gmail.com> | 2010-09-04 00:31:35 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2010-09-04 00:31:43 +0200 |
commit | 23a9455962f0362cf242ffa96db7a9e7fdb0804b (patch) | |
tree | c046d1285d078649db6833fa1b73a6c23f7f16ea /actionpack/lib | |
parent | 63032c1162e96d3380168ca63ac42aa044dbebd6 (diff) | |
parent | c3c1a1e14859e6716970283caeab0c4c3720862e (diff) | |
download | rails-23a9455962f0362cf242ffa96db7a9e7fdb0804b.tar.gz rails-23a9455962f0362cf242ffa96db7a9e7fdb0804b.tar.bz2 rails-23a9455962f0362cf242ffa96db7a9e7fdb0804b.zip |
This commit merges most of the work done by Piotr Sarnacki in his Ruby Summer of Code project.
His work brings several capabilities from app to engines, as routes, middleware stack, asset handling and much more. Please check Rails::Engine documentation for more refenrences.
Merge remote branch 'drogus/engines'
Diffstat (limited to 'actionpack/lib')
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) |