diff options
author | Andrew White <andrew.white@unboxed.co> | 2017-02-21 15:29:10 +0000 |
---|---|---|
committer | Andrew White <andrew.white@unboxed.co> | 2017-02-21 15:30:48 +0000 |
commit | d7c1e62c2cd2969b991bc4a1150b02b27f6d6e3f (patch) | |
tree | 184406df10d1e8ebabc4970b15c8bbf113955c39 /actionpack/lib | |
parent | fbda6b9837e3ce41dc59de0e791c972ba6d49ba3 (diff) | |
download | rails-d7c1e62c2cd2969b991bc4a1150b02b27f6d6e3f.tar.gz rails-d7c1e62c2cd2969b991bc4a1150b02b27f6d6e3f.tar.bz2 rails-d7c1e62c2cd2969b991bc4a1150b02b27f6d6e3f.zip |
Split direct method into two
Use a separate method called `resolve` for the custom polymorphic
mapping to clarify the API.
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 91 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 14 |
2 files changed, 56 insertions, 49 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 4fc76e8591..8b4ce1ed6a 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -2020,8 +2020,8 @@ module ActionDispatch end end - module DirectUrls - # Define custom routing behavior that will be added to the application's + module CustomUrls + # Define custom url helpers that will be added to the application's # routes. This allows you override and/or replace the default behavior # of routing helpers, e.g: # @@ -2037,14 +2037,49 @@ module ActionDispatch # { controller: 'pages', action: 'index', subdomain: 'www' } # end # - # The above example show how to define a custom url helper but it's also - # possible to alter the behavior of `polymorphic_url` and consequently the - # behavior of `link_to` and `form_for` when passed a model instance, e.g: + # The return value from the block passed to `direct` must be a valid set of + # arguments for `url_for` which will actually build the url string. This can + # be one of the following: + # + # * A string, which is treated as a generated url + # * A hash, e.g. { controller: 'pages', action: 'index' } + # * An array, which is passed to `polymorphic_url` + # * An Active Model instance + # * An Active Model class + # + # NOTE: Other url helpers can be called in the block but be careful not to invoke + # your custom url helper again otherwise it will result in a stack overflow error + # + # You can also specify default options that will be passed through to + # your url helper definition, e.g: + # + # direct :browse, page: 1, size: 10 do |options| + # [ :products, options.merge(params.permit(:page, :size)) ] + # end + # + # NOTE: The `direct` methodn can't be used inside of a scope block such as + # `namespace` or `scope` and will raise an error if it detects that it is. + def direct(name, options = {}, &block) + unless @scope.root? + raise RuntimeError, "The direct method can't be used inside a routes scope block" + end + + @set.add_url_helper(name, options, &block) + end + + # Define custom polymorphic mappings of models to urls. This alters the + # behavior of `polymorphic_url` and consequently the behavior of + # `link_to` and `form_for` when passed a model instance, e.g: # - # direct class: "Basket" do + # resource :basket + # + # resolve "Basket" do # [:basket] # end # + # This will now generate '/basket' when a `Basket` instance is passed to + # `link_to` or `form_for` instead of the standard '/baskets/:id'. + # # NOTE: This custom behavior only applies to simple polymorphic urls where # a single model instance is passed and not more complicated forms, e.g: # @@ -2054,7 +2089,7 @@ module ActionDispatch # resources :users # end # - # direct(class: "User") { [:profile] } + # resolve("User") { [:profile] } # # # app/views/application/_menu.html.erb # link_to 'Profile', @current_user @@ -2063,27 +2098,7 @@ module ActionDispatch # The first `link_to` will generate '/profile' but the second will generate # the standard polymorphic url of '/admin/users/1'. # - # The return value from the block passed to `direct` must be a valid set of - # arguments for `url_for` which will actually build the url string. This can - # be one of the following: - # - # * A string, which is treated as a generated url - # * A hash, e.g. { controller: 'pages', action: 'index' } - # * An array, which is passed to `polymorphic_url` - # * An Active Model instance - # * An Active Model class - # - # NOTE: Other url helpers can be called in the block but be careful not to invoke - # your custom url helper again otherwise it will result in a stack overflow error - # - # You can also specify default options that will be passed through to - # your url helper definition, e.g: - # - # direct :browse, page: 1, size: 10 do |options| - # [ :products, options.merge(params.permit(:page, :size)) ] - # end - # - # You can pass options to a polymorphic mapping do - the arity for the block + # You can pass options to a polymorphic mapping - the arity for the block # needs to be two as the instance is passed as the first argument, e.g: # # direct class: 'Basket', anchor: 'items' do |basket, options| @@ -2094,20 +2109,18 @@ module ActionDispatch # array passed to `polymorphic_url` is a hash then it's treated as options # to the url helper that gets called. # - # NOTE: The `direct` methodn can't be used inside of a scope block such as + # NOTE: The `resolve` methodn can't be used inside of a scope block such as # `namespace` or `scope` and will raise an error if it detects that it is. - def direct(name_or_hash, options = nil, &block) + def resolve(*args, &block) unless @scope.root? - raise RuntimeError, "The direct method can't be used inside a routes scope block" + raise RuntimeError, "The resolve method can't be used inside a routes scope block" end - case name_or_hash - when Hash - @set.add_polymorphic_mapping(name_or_hash, &block) - when String, Symbol - @set.add_url_helper(name_or_hash, options, &block) - else - raise ArgumentError, "The direct method only accepts a hash, string or symbol" + options = args.extract_options! + args = args.flatten(1) + + args.each do |klass| + @set.add_polymorphic_mapping(klass, options, &block) end end end @@ -2213,7 +2226,7 @@ module ActionDispatch include Scoping include Concerns include Resources - include DirectUrls + include CustomUrls end end end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index a2e5351697..84457c97de 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -160,7 +160,7 @@ module ActionDispatch def add_url_helper(name, defaults, &block) @custom_helpers << name - helper = DirectUrlHelper.new(name, defaults, &block) + helper = CustomUrlHelper.new(name, defaults, &block) @path_helpers_module.module_eval do define_method(:"#{name}_path") do |*args| @@ -596,21 +596,15 @@ module ActionDispatch route end - def add_polymorphic_mapping(options, &block) - defaults = options.dup - klass = defaults.delete(:class) - if klass.nil? - raise ArgumentError, "Missing :class key from polymorphic mapping options" - end - - @polymorphic_mappings[klass] = DirectUrlHelper.new(klass, defaults, &block) + def add_polymorphic_mapping(klass, options, &block) + @polymorphic_mappings[klass] = CustomUrlHelper.new(klass, options, &block) end def add_url_helper(name, options, &block) named_routes.add_url_helper(name, options, &block) end - class DirectUrlHelper + class CustomUrlHelper attr_reader :name, :defaults, :block def initialize(name, defaults, &block) |