4

Supposing the route

map.resources :articles

how do you get this

/articles?most_popular

using link_to method?

tried the following:

link_to articles_path(:most_popular) # exception
link_to articles_path(:most_popular => nil) # /articles
link_to articles_path(:most_popular => true) # /articles?most_popular=true

note: i'm using inherited_resources with has_scope

knoopx
  • 17,089
  • 7
  • 36
  • 41

3 Answers3

4

If you don't add a value to the parameters you will not be respecting the W3C standard, which mandates that the params section has the form field=value.

I recommend that you add a new :most_popular action to your articles controller instead.

On your routes.rb:

map.resources :articles, :collection => {:most_popular=>:get}

On your controller:

class ArticlesController < ApplicationController
...
def most_popular
  @articles = ...
end

On your views:

link_to most_popular_articles_path() # /articles/most_popular

This will be HTML-compliant, your urls will look practically the same (changing one ? by one /) and your controller will be simplified (you will have the most_popular action separated from the index).

Regards!

Update (2017): It appears that the W3C standard doesn't mandate the field=value syntax (or doesn't mandate it any more). However some servers are documented to "choke" on queries not complying with this syntax. See Is a url query parameter valid if it has no value? for details.

kikito
  • 51,734
  • 32
  • 149
  • 189
  • I do code exactly like this. However I started to refactor my code lately and wonder how RESTFUL and/or recoomoended it this approach. Is not the "most popular" rather a assitional filter to index, so rather a query option (filter=most_popular) – gorn Nov 18 '13 at 21:12
  • 1
    Restful doesn't mean CRUD-only. It means that every url can be tought of as a resource. The question is: are the most popular articles different enough from the regular articles to deserve their own resource? The answer is not "I must have CRUD". It's "it depends on the application". If they are not very important, adding a filter param would be enough. If they were super important, they would deserve their own controller, probably. My solution is intermediate. – kikito Nov 21 '13 at 10:20
  • Yes, this is very insighteful. Thanks gorn – gorn Apr 12 '14 at 17:48
  • 1
    @kikito Can you back up that assertion with a link to "the W3C standard"? – mb21 Sep 06 '16 at 16:14
  • @mb21 You might not have noticed that I answered this in 2009 - seven years ago. I probably googled it up somewhere back then. I should have put the link there and I apologize. I am afraid that I can't invest time in googling it up again now. But if you do find it, please include it in a comment. – kikito Sep 07 '16 at 14:40
  • @kikito I tried googling it but came up empty... some standards [definitely allow it](http://stackoverflow.com/questions/4557387/is-a-url-query-parameter-valid-if-it-has-no-value)... that's why I was asking... – mb21 Sep 08 '16 at 14:09
  • Well, on that page you sent me there is a [link to the w3c (HTML spec)](https://www.w3.org/TR/html401/interact/forms.html#form-content-type). This is probably what I read. – kikito Sep 09 '16 at 09:36
  • The `?key=val&...` format is standard for including forms with a GET request, but to my knowledge there's nothing that says a URL needs to have a query string formatted that way in order to be valid. – johncip Aug 08 '17 at 05:15
  • Fair enough. I added an update to the bottom of the question. – kikito Aug 08 '17 at 11:10
1

The last example you have:

link_to articles_path(:most_popular => true) # /articles?most_popular=true

Is the correct way. Otherwise you could just construct the link by hand:

<a href="<%= articles_path %>?most_popular">articles</a>
rfunduk
  • 30,053
  • 5
  • 59
  • 54
1

See https://stackoverflow.com/a/4557763/803804

The spec doesn't mandate the ?key=value format and in fact ?key is just fine.

In addition Rails (and most frameworks) will handle it.

In the case of Rails it will convert this into params that look like { 'key' => nil }

Unfortunately passing a param into the rails url helpers with a value of nil will result in that param not being added to the querystring so the only way I've found to do that is articles_path + "?most_popular"

Paul Odeon
  • 4,407
  • 1
  • 37
  • 37