Always use original url_for when generating direct routes

Action View overrides `url_for` in the view context to render paths by
default when using `url_for` and this means that direct route helpers
don't get the full url when called with the url suffix. To fix this
always call the original `url_for`.
This commit is contained in:
Andrew White 2017-03-17 21:30:29 +00:00
parent bac40b9cc8
commit fd16e1a92f
3 changed files with 55 additions and 1 deletions

@ -509,6 +509,10 @@ def url_for(options)
@_proxy.url_for(options)
end
def full_url_for(options)
@_proxy.full_url_for(options)
end
def route_for(name, *args)
@_proxy.route_for(name, *args)
end
@ -619,7 +623,7 @@ def initialize(name, defaults, &block)
def call(t, args, only_path = false)
options = args.extract_options!
url = t.url_for(eval_block(t, args, options))
url = t.full_url_for(eval_block(t, args, options))
if only_path
"/" + url.partition(%r{(?<!/)/(?!/)}).last

@ -164,6 +164,10 @@ def url_options
# implicitly used by +url_for+ can always be overwritten like shown on the
# last +url_for+ calls.
def url_for(options = nil)
full_url_for(options)
end
def full_url_for(options = nil) # :nodoc:
case options
when nil
_routes.url_for(url_options.symbolize_keys)

@ -730,3 +730,49 @@ def assert_url(url, args)
assert_equal url.sub(/http:\/\/#{host}/, ""), url_for(args)
end
end
class DirectRoutesTest < ActionView::TestCase
class Linkable
attr_reader :id
def self.name
super.demodulize
end
def initialize(id)
@id = id
end
def linkable_type
self.class.name.underscore
end
end
class Category < Linkable; end
class Collection < Linkable; end
class Product < Linkable; end
Routes = ActionDispatch::Routing::RouteSet.new
Routes.draw do
resources :categories, :collections, :products
direct(:linkable) { |linkable| [:"#{linkable.linkable_type}", { id: linkable.id }] }
end
include Routes.url_helpers
def setup
@category = Category.new("1")
@collection = Collection.new("2")
@product = Product.new("3")
end
def test_direct_routes
assert_equal "/categories/1", linkable_path(@category)
assert_equal "/collections/2", linkable_path(@collection)
assert_equal "/products/3", linkable_path(@product)
assert_equal "http://test.host/categories/1", linkable_url(@category)
assert_equal "http://test.host/collections/2", linkable_url(@collection)
assert_equal "http://test.host/products/3", linkable_url(@product)
end
end