Full URL with url_for in Rails

前端 未结 6 1537
别那么骄傲
别那么骄傲 2020-12-28 15:34

How can I get a full url in rails?

url_for @book is returning only a path like /book/1 and not www.domain.com/book/1

Thanks (and sorry if the answer is obvio

相关标签:
6条回答
  • 2020-12-28 15:54

    According to the docs, this shouldn't happen. The option you're looking for is :only_path and it's false by default. What happens if you set it to false explicitly?

    url_for(@book, :only_path => false)
    

    While you can use url_for you should prefer Ryan's method when you can - book_url(@book) for a full url or book_path(@book) for the path.

    0 讨论(0)
  • 2020-12-28 15:59

    In Rails 4, url_for only takes one argument, so you need to pass an array with an explicit hash inside for the only_path option.

    Good:

    url_for([@post, @comment, {only_path: true}])
    

    Bad:

    url_for(@post, @comment, {only_path: true})
    url_for([@post, @comment], {only_path: true})
    

    From the source, url_for with an Array input just calls:

    polymorphic_url([@post, @comment], {only_path: true})
    

    as shown in @moose's answer.

    As noted by @lime, only_path is generally not needed for polymorphic_url since you distinguish that with the _url _path suffixes.

    0 讨论(0)
  • 2020-12-28 16:10

    Use the :host option. For example, you can use:

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

    Note: with Rails 3 and above, use polymorphic_url instead of url_for.

    0 讨论(0)
  • 2020-12-28 16:12

    In Rails 5, if you want the full url for the current controller/action (== current page), just use:

    url_for(only_path: false)
    

    Long answer:

    In Rails 5, url_for in a view is ActionView::RoutingUrlFor#url_for. If you look at it's source code (https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for), you'll see if you pass a Hash (keyword parameters are cast into a Hash by Ruby), it actually calls super, thus invoking the method of same name in it's ancestor.

    ActionView::RoutingUrlFor.ancestors reveals that it's first ancestor is ActionDispatch::Routing::UrlFor.

    Checking it's source code (https://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for), you'll read this:

    Missing routes keys may be filled in from the current request's parameters (e.g. :controller, :action, :id and any other parameters that are placed in the path).

    This is very nice, since it will build automatically a URL for you for the current page (or path, if you just invoke url_for without the only_path: false). It will also intelligently ignore the query string params; if you need to merge those, you can use url_for(request.params.merge({arbitrary_argument:'value'})).

    0 讨论(0)
  • 2020-12-28 16:14

    It seems that this would work:

    url_for(@book)
    

    But it does not. The url_for method accepts only one argument, which can be either a string, an instance of a model, or a hash of options. This is rather unfortunate, as it would seem like you may need to link to @book and add options like :only_path or :host as well.

    One way around it is to use polymorphic_url, which would render the correct absolute url even though your model is (likely) not actually polymorphic:

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

    Perhaps the best route would be to use a named route, which is set up automatically for you when declaring resources in your routes or using the :as option:

    # in routes.rb:
    resources :books
    # or
    get "books/:id" => "books#show", as: :book
    
    # in your view:
    book_path(@book, :host => "domain.com")
    
    0 讨论(0)
  • 2020-12-28 16:16

    If it's a RESTful resource you'll be able to use this:

    book_url(@book)
    
    0 讨论(0)
提交回复
热议问题