【发布时间】:2011-03-30 05:23:02
【问题描述】:
如何在 rails 中获取完整的 url?
url_for @book 只返回 /book/1 之类的路径,而不是 www.domain.com/book/1
谢谢(如果答案很明显,我很抱歉。我正在学习 rails!)
【问题讨论】:
标签: ruby-on-rails
如何在 rails 中获取完整的 url?
url_for @book 只返回 /book/1 之类的路径,而不是 www.domain.com/book/1
谢谢(如果答案很明显,我很抱歉。我正在学习 rails!)
【问题讨论】:
标签: ruby-on-rails
根据the docs,这不应该发生。您要查找的选项是 :only_path,默认情况下为 false。如果将其显式设置为 false 会发生什么?
url_for(@book, :only_path => false)
虽然您可以使用 url_for,但如果可以,您应该更喜欢 Ryan 的方法 - book_url(@book) 用于完整 URL 或 book_path(@book) 用于路径。
【讨论】:
link_to(@book.title, book_path(@book, only_path: false)) 为我工作(Rails 3)
如果它是 RESTful 资源,您将能够使用它:
book_url(@book)
【讨论】:
url_for 是 DRYer,因为它不会复制您正在谈论的模型,自动处理多态性。
在 Rails 4 中,url_for only takes one argument,因此您需要为 only_path 选项传递一个包含显式哈希的数组。
好:
url_for([@post, @comment, {only_path: true}])
不好:
url_for(@post, @comment, {only_path: true})
url_for([@post, @comment], {only_path: true})
从源代码中,url_for 带有 Array 输入只是调用:
polymorphic_url([@post, @comment], {only_path: true})
如@moose 的回答所示。
正如@lime 所指出的,polymorphic_url 通常不需要only_path,因为您可以通过_url _path 后缀来区分它。
【讨论】:
#<NoMethodError: undefined method `model_name' for Hash:Class>... 将调查。
polymorphic_url。这样,我可以在方法名称中的 _url 和 _path 之间进行选择,而不是传递哈希值。仍然不知道是什么导致了错误。
这似乎可行:
url_for(@book)
但事实并非如此。 url_for 方法只接受一个参数,可以是字符串、模型实例或选项哈希。这是相当不幸的,因为您可能需要链接到@book 并添加诸如 :only_path 或 :host 之类的选项。
解决它的一种方法是使用 polymorphic_url,即使您的模型(可能)实际上不是多态的,它也会呈现正确的绝对 url:
polymorphic_url(@book, :host => "domain.com")
也许最好的路由是使用命名路由,它会在您的路由中声明资源或使用 :as 选项时自动为您设置:
# in routes.rb:
resources :books
# or
get "books/:id" => "books#show", as: :book
# in your view:
book_path(@book, :host => "domain.com")
【讨论】:
使用 :host 选项。例如,您可以使用:
url_for(@book, :host => "domain.com")
注意:对于 Rails 3 及更高版本,请使用 polymorphic_url 而不是 url_for。
【讨论】:
url_for 调用 polymorphic_url。
polymorphic_url api.rubyonrails.org/classes/ActionDispatch/Routing/… 的链接,我将它与polymorphic_url(object, subdomain: "something") 之类的对象一起使用
在 Rails 5 中,如果您想要当前控制器/动作的完整 url(== 当前页面),只需使用:
url_for(only_path: false)
长答案:
在 Rails 5 中,视图中的url_for 是ActionView::RoutingUrlFor#url_for。如果你看它的源代码(https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for),你会看到如果你传递了一个Hash(关键字参数被Ruby转换为一个Hash),它实际上调用了super,从而调用了它的同名方法祖先。
ActionView::RoutingUrlFor.ancestors 表明它的第一个祖先是ActionDispatch::Routing::UrlFor。
查看它的源代码 (https://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for),你会看到:
缺少的路由键可以从当前请求的 参数(例如 :controller、:action、:id 和任何其他参数 放置在路径中)。
这非常好,因为它会自动为您构建当前页面的 URL(或路径,如果您只调用 url_for 而没有 only_path: false)。它还会智能地忽略查询字符串参数;如果你需要合并这些,你可以使用url_for(request.params.merge({arbitrary_argument:'value'}))。
【讨论】: