Extended url_for to handle specifying which router should be used.
A few examples: url_for Blog::Engine, :posts_path url_for Blog::Engine, @post url_for Blog::Engine, :action => "main", :controller => "index"
This commit is contained in:
parent
b697ba9fd7
commit
b53efd2105
@ -111,7 +111,7 @@ def polymorphic_url(record_or_hash_or_array, options = {})
|
|||||||
args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
|
args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
|
||||||
end
|
end
|
||||||
|
|
||||||
send(named_route, *args)
|
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
|
# Returns the path component of a URL for the given record. It uses
|
||||||
|
@ -158,10 +158,17 @@ def define_hash_access(route, name, kind, options)
|
|||||||
|
|
||||||
# We use module_eval to avoid leaks
|
# We use module_eval to avoid leaks
|
||||||
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
|
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
|
||||||
def #{selector}(options = nil) # def hash_for_users_url(options = nil)
|
def #{selector}(*args)
|
||||||
options ? #{options.inspect}.merge(options) : #{options.inspect} # options ? {:only_path=>false}.merge(options) : {:only_path=>false}
|
options = args.extract_options!
|
||||||
end # end
|
|
||||||
protected :#{selector} # protected :hash_for_users_url
|
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
|
END_EVAL
|
||||||
helpers << selector
|
helpers << selector
|
||||||
end
|
end
|
||||||
@ -185,14 +192,7 @@ def define_url_helper(route, name, kind, options)
|
|||||||
|
|
||||||
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
|
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
|
||||||
def #{selector}(*args)
|
def #{selector}(*args)
|
||||||
options = #{hash_access_method}(args.extract_options!)
|
url_for(#{hash_access_method}(*args))
|
||||||
|
|
||||||
if args.any?
|
|
||||||
options[:_positional_args] = args
|
|
||||||
options[:_positional_keys] = #{route.segment_keys.inspect}
|
|
||||||
end
|
|
||||||
|
|
||||||
url_for(options)
|
|
||||||
end
|
end
|
||||||
END_EVAL
|
END_EVAL
|
||||||
helpers << selector
|
helpers << selector
|
||||||
|
@ -123,13 +123,24 @@ def url_options
|
|||||||
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
|
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
|
||||||
# url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
|
# url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
|
||||||
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
|
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
|
||||||
def url_for(options = nil)
|
def url_for(*args)
|
||||||
|
if args.first.respond_to?(:routes)
|
||||||
|
app = args.shift
|
||||||
|
_with_routes(app.routes) do
|
||||||
|
if args.first.is_a? Symbol
|
||||||
|
named_route = args.shift
|
||||||
|
url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args)
|
||||||
|
else
|
||||||
|
url_for(*args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
options = args.first
|
||||||
case options
|
case options
|
||||||
when String
|
when String
|
||||||
options
|
options
|
||||||
when nil, Hash
|
when nil, Hash
|
||||||
routes = (options ? options.delete(:routes) : nil) || _routes
|
routes = (options ? options.delete(:routes) : nil) || _routes
|
||||||
|
|
||||||
_with_routes(routes) do
|
_with_routes(routes) do
|
||||||
routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys)
|
routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys)
|
||||||
end
|
end
|
||||||
@ -137,7 +148,9 @@ def url_for(options = nil)
|
|||||||
polymorphic_url(options)
|
polymorphic_url(options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
def _with_routes(routes)
|
def _with_routes(routes)
|
||||||
old_routes, @_routes = @_routes, routes
|
old_routes, @_routes = @_routes, routes
|
||||||
yield
|
yield
|
||||||
|
52
actionpack/test/dispatch/url_for_test.rb
Normal file
52
actionpack/test/dispatch/url_for_test.rb
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
require 'abstract_unit'
|
||||||
|
|
||||||
|
module UrlForGeneration
|
||||||
|
class UrlForTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
|
Routes = ActionDispatch::Routing::RouteSet.new
|
||||||
|
Routes.draw { match "/foo", :to => "my_route_generating#index", :as => :foo }
|
||||||
|
|
||||||
|
class BlogEngine
|
||||||
|
def self.routes
|
||||||
|
@routes ||= begin
|
||||||
|
routes = ActionDispatch::Routing::RouteSet.new
|
||||||
|
routes.draw do
|
||||||
|
resources :posts
|
||||||
|
end
|
||||||
|
routes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Post
|
||||||
|
extend ActiveModel::Naming
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
"1"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.model_name
|
||||||
|
klass = "Post"
|
||||||
|
def klass.name; self end
|
||||||
|
|
||||||
|
ActiveModel::Name.new(klass)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
include Routes.url_helpers
|
||||||
|
|
||||||
|
test "url_for with named url helpers" do
|
||||||
|
assert_equal "/posts", url_for(BlogEngine, :posts_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "url_for with polymorphic routes" do
|
||||||
|
assert_equal "http://www.example.com/posts/1", url_for(BlogEngine, Post.new)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "url_for with named url helper with arguments" do
|
||||||
|
assert_equal "/posts/1", url_for(BlogEngine, :post_path, 1)
|
||||||
|
assert_equal "/posts/1", url_for(BlogEngine, :post_path, :id => 1)
|
||||||
|
assert_equal "/posts/1.json", url_for(BlogEngine, :post_path, :id => 1, :format => :json)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -41,3 +41,4 @@ def app
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -77,13 +77,35 @@ def @post.to_param; '123'; end
|
|||||||
@post.written_on = Date.new(2004, 6, 15)
|
@post.written_on = Date.new(2004, 6, 15)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Routes = ActionDispatch::Routing::RouteSet.new
|
||||||
|
Routes.draw do
|
||||||
|
resources :posts do
|
||||||
|
resources :comments
|
||||||
|
end
|
||||||
|
|
||||||
|
namespace :admin do
|
||||||
|
resources :posts do
|
||||||
|
resources :comments
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
match "/foo", :to => "controller#action"
|
||||||
|
root :to => "main#index"
|
||||||
|
end
|
||||||
|
|
||||||
|
def _routes
|
||||||
|
Routes
|
||||||
|
end
|
||||||
|
|
||||||
|
include Routes.url_helpers
|
||||||
|
|
||||||
def url_for(object)
|
def url_for(object)
|
||||||
@url_for_options = object
|
@url_for_options = object
|
||||||
if object.is_a?(Hash)
|
if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank?
|
||||||
"http://www.example.com"
|
object.merge!(:controller => "main", :action => "index")
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
end
|
||||||
|
object
|
||||||
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_label
|
def test_label
|
||||||
@ -628,7 +650,7 @@ def test_form_for
|
|||||||
end
|
end
|
||||||
|
|
||||||
expected =
|
expected =
|
||||||
"<form accept-charset='UTF-8' action='http://www.example.com' id='create-post' method='post'>" +
|
"<form accept-charset='UTF-8' action='/' id='create-post' method='post'>" +
|
||||||
snowman +
|
snowman +
|
||||||
"<label for='post_title'>The Title</label>" +
|
"<label for='post_title'>The Title</label>" +
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
@ -683,7 +705,7 @@ def test_form_for_with_method
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = whole_form("http://www.example.com", "create-post", nil, "put") do
|
expected = whole_form("/", "create-post", nil, "put") do
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||||
@ -702,7 +724,7 @@ def test_form_for_with_remote
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = whole_form("http://www.example.com", "create-post", nil, :method => "put", :remote => true) do
|
expected = whole_form("/", "create-post", nil, :method => "put", :remote => true) do
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||||
@ -721,7 +743,7 @@ def test_form_for_with_remote_without_html
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = whole_form("http://www.example.com", nil, nil, :remote => true) do
|
expected = whole_form("/", nil, nil, :remote => true) do
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||||
@ -738,7 +760,7 @@ def test_form_for_without_object
|
|||||||
concat f.check_box(:secret)
|
concat f.check_box(:secret)
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = whole_form("http://www.example.com", "create-post") do
|
expected = whole_form("/", "create-post") do
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||||
@ -1478,7 +1500,7 @@ def test_form_for_and_fields_for
|
|||||||
end
|
end
|
||||||
|
|
||||||
expected =
|
expected =
|
||||||
"<form accept-charset='UTF-8' action='http://www.example.com' id='create-post' method='post'>" +
|
"<form accept-charset='UTF-8' action='/' id='create-post' method='post'>" +
|
||||||
snowman +
|
snowman +
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||||
@ -1502,7 +1524,7 @@ def test_form_for_and_fields_for_with_object
|
|||||||
end
|
end
|
||||||
|
|
||||||
expected =
|
expected =
|
||||||
whole_form("http://www.example.com", "create-post") do
|
whole_form("/", "create-post") do
|
||||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||||
"<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />"
|
"<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />"
|
||||||
@ -1546,7 +1568,7 @@ def snowman(method = nil)
|
|||||||
txt << %{</div>}
|
txt << %{</div>}
|
||||||
end
|
end
|
||||||
|
|
||||||
def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil)
|
def form_text(action = "/", id = nil, html_class = nil, remote = nil)
|
||||||
txt = %{<form accept-charset="UTF-8" action="#{action}"}
|
txt = %{<form accept-charset="UTF-8" action="#{action}"}
|
||||||
txt << %{ data-remote="true"} if remote
|
txt << %{ data-remote="true"} if remote
|
||||||
txt << %{ class="#{html_class}"} if html_class
|
txt << %{ class="#{html_class}"} if html_class
|
||||||
@ -1554,7 +1576,7 @@ def form_text(action = "http://www.example.com", id = nil, html_class = nil, rem
|
|||||||
txt << %{ method="post">}
|
txt << %{ method="post">}
|
||||||
end
|
end
|
||||||
|
|
||||||
def whole_form(action = "http://www.example.com", id = nil, html_class = nil, options = nil)
|
def whole_form(action = "/", id = nil, html_class = nil, options = nil)
|
||||||
contents = block_given? ? yield : ""
|
contents = block_given? ? yield : ""
|
||||||
|
|
||||||
if options.is_a?(Hash)
|
if options.is_a?(Hash)
|
||||||
@ -1655,7 +1677,7 @@ def test_form_for_with_html_options_adds_options_to_form_tag
|
|||||||
assert_deprecated do
|
assert_deprecated do
|
||||||
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
|
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
|
||||||
end
|
end
|
||||||
expected = whole_form("http://www.example.com", "some_form", "some_class")
|
expected = whole_form("/", "some_form", "some_class")
|
||||||
|
|
||||||
assert_dom_equal expected, output_buffer
|
assert_dom_equal expected, output_buffer
|
||||||
end
|
end
|
||||||
@ -1710,14 +1732,14 @@ def test_form_for_with_existing_object_in_list
|
|||||||
@comment.save
|
@comment.save
|
||||||
form_for([@post, @comment]) {}
|
form_for([@post, @comment]) {}
|
||||||
|
|
||||||
expected = whole_form(comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put")
|
expected = whole_form(post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put")
|
||||||
assert_dom_equal expected, output_buffer
|
assert_dom_equal expected, output_buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_form_for_with_new_object_in_list
|
def test_form_for_with_new_object_in_list
|
||||||
form_for([@post, @comment]) {}
|
form_for([@post, @comment]) {}
|
||||||
|
|
||||||
expected = whole_form(comments_path(@post), "new_comment", "new_comment")
|
expected = whole_form(post_comments_path(@post), "new_comment", "new_comment")
|
||||||
assert_dom_equal expected, output_buffer
|
assert_dom_equal expected, output_buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1725,14 +1747,14 @@ def test_form_for_with_existing_object_and_namespace_in_list
|
|||||||
@comment.save
|
@comment.save
|
||||||
form_for([:admin, @post, @comment]) {}
|
form_for([:admin, @post, @comment]) {}
|
||||||
|
|
||||||
expected = whole_form(admin_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put")
|
expected = whole_form(admin_post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put")
|
||||||
assert_dom_equal expected, output_buffer
|
assert_dom_equal expected, output_buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_form_for_with_new_object_and_namespace_in_list
|
def test_form_for_with_new_object_and_namespace_in_list
|
||||||
form_for([:admin, @post, @comment]) {}
|
form_for([:admin, @post, @comment]) {}
|
||||||
|
|
||||||
expected = whole_form(admin_comments_path(@post), "new_comment", "new_comment")
|
expected = whole_form(admin_post_comments_path(@post), "new_comment", "new_comment")
|
||||||
assert_dom_equal expected, output_buffer
|
assert_dom_equal expected, output_buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1749,38 +1771,6 @@ def test_fields_for_returns_block_result
|
|||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def comments_path(post)
|
|
||||||
"/posts/#{post.id}/comments"
|
|
||||||
end
|
|
||||||
alias_method :post_comments_path, :comments_path
|
|
||||||
|
|
||||||
def comment_path(post, comment)
|
|
||||||
"/posts/#{post.id}/comments/#{comment.id}"
|
|
||||||
end
|
|
||||||
alias_method :post_comment_path, :comment_path
|
|
||||||
|
|
||||||
def admin_comments_path(post)
|
|
||||||
"/admin/posts/#{post.id}/comments"
|
|
||||||
end
|
|
||||||
alias_method :admin_post_comments_path, :admin_comments_path
|
|
||||||
|
|
||||||
def admin_comment_path(post, comment)
|
|
||||||
"/admin/posts/#{post.id}/comments/#{comment.id}"
|
|
||||||
end
|
|
||||||
alias_method :admin_post_comment_path, :admin_comment_path
|
|
||||||
|
|
||||||
def posts_path
|
|
||||||
"/posts"
|
|
||||||
end
|
|
||||||
|
|
||||||
def post_path(post, options = {})
|
|
||||||
if options[:format]
|
|
||||||
"/posts/#{post.id}.#{options[:format]}"
|
|
||||||
else
|
|
||||||
"/posts/#{post.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def protect_against_forgery?
|
def protect_against_forgery?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ def test_link_to_person
|
|||||||
with_test_route_set do
|
with_test_route_set do
|
||||||
person = mock(:name => "David")
|
person = mock(:name => "David")
|
||||||
person.class.extend ActiveModel::Naming
|
person.class.extend ActiveModel::Naming
|
||||||
expects(:mocha_mock_path).with(person).returns("/people/1")
|
_routes.url_helpers.expects(:hash_for_mocha_mock_path).with(person).returns("/people/1")
|
||||||
assert_equal '<a href="/people/1">David</a>', link_to_person(person)
|
assert_equal '<a href="/people/1">David</a>', link_to_person(person)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user