【问题标题】:Full URL with url_for in RailsRails 中带有 url_for 的完整 URL
【发布时间】:2011-03-30 05:23:02
【问题描述】:

如何在 rails 中获取完整的 url?

url_for @book 只返回 /book/1 之类的路径,而不是 www.domain.com/book/1

谢谢(如果答案很明显,我很抱歉。我正在学习 rails!)

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    根据the docs,这不应该发生。您要查找的选项是 :only_path,默认情况下为 false。如果将其显式设置为 false 会发生什么?

    url_for(@book, :only_path => false)
    

    虽然您可以使用 url_for,但如果可以,您应该更喜欢 Ryan 的方法 - book_url(@book) 用于完整 URL 或 book_path(@book) 用于路径。

    【讨论】:

    • 添加 :only_path => false 使用 rails 3.1.1 为我解决了这个问题
    • url_for(@book, :only_path => false) 在这里引发异常,因为您在预期 1 时传入了 2 个参数。似乎他们会构建此方法来接受选项,但在最新版本的 rails 它只接受一个:字符串/实例或选项哈希。
    • link_to(@book.title, book_path(@book, only_path: false)) 为我工作(Rails 3)
    • @amoose 在 Rails 4 中,可以通过数组传递哈希值和更多参数,请参阅 my answer
    【解决方案2】:

    如果它是 RESTful 资源,您将能够使用它:

    book_url(@book)
    

    【讨论】:

    • url_for 是 DRYer,因为它不会复制您正在谈论的模型,自动处理多态性。
    【解决方案3】:

    在 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>... 将调查。
    • @lime 很奇怪,它似乎对我的测试有效,我将它推送到 gitlab:github.com/gitlabhq/gitlabhq/blob/… 如果你发现了什么,请告诉我。
    • 是的,我最终直接使用了polymorphic_url。这样,我可以在方法名称中的 _url_path 之间进行选择,而不是传递哈希值。仍然不知道是什么导致了错误。
    【解决方案4】:

    这似乎可行:

    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' 参数传递给 polymorphic_url。要获取相对路径,您可以使用 polymorphic_path。
    【解决方案5】:

    使用 :host 选项。例如,您可以使用:

    url_for(@book, :host => "domain.com")
    

    注意:对于 Rails 3 及更高版本,请使用 polymorphic_url 而不是 url_for

    【讨论】:

    • 我认为 Rails 3 不支持这一点 - 使用 polymorphic_url 可能会更好
    • 这不适用于最新版本的 Rails(> 3.2 甚至可能是 3.1)。 url_for 只接受一个参数,可以是字符串、模型实例或选项哈希。
    • 在 rails 4 url_for 调用 polymorphic_url
    • 这是polymorphic_url api.rubyonrails.org/classes/ActionDispatch/Routing/… 的链接,我将它与polymorphic_url(object, subdomain: "something") 之类的对象一起使用
    【解决方案6】:

    在 Rails 5 中,如果您想要当前控制器/动作的完整 url(== 当前页面),只需使用:

    url_for(only_path: false)
    

    长答案:

    在 Rails 5 中,视图中的url_forActionView::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'}))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 1970-01-01
      • 2018-04-03
      • 2011-07-25
      • 2012-04-28
      相关资源
      最近更新 更多