开发者

How to match hash (deep nested) params in Rails3 to make a pretty URL?

开发者 https://www.devze.com 2023-04-04 09:03 出处:网络
If I have this route (in routes.rb): match \'posts\', :to => \'posts#index\' It will show and match the following routes:

If I have this route (in routes.rb):

match 'posts', :to => 'posts#index'

It will show and match the following routes:

# Case 1: non nested hash params
posts_path(:search => 'the', :category => 'old-school')
#=> "/posts?search=the&category=old-school"

# Case 2: nes开发者_开发技巧ted hash params
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts?filter[search]=the&filter[category]=old-school"

If I want to make the category param part of the main URL, I could do this for the Case 1.

match 'posts(/:category)', :to => 'posts#index'

that will show and match the following routes:

# Case 1: non nested hash params
posts_path(:search => 'the', :category => 'old-school')
#=> "/posts/old-school?search=the"

But how could I do the same if the param is nested (Case 2)?

I would expect the next route definition:

match 'posts(/:filter[category])', :to => 'posts#index'

to work this way:

# Case 2: nested hash params
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts/old-school?filter[search]=the"

But it does not work.

I found this same question in two places with no righ answer:

  • how-to-specify-nested-parameters-in-the-routes
  • how-to-accept-hash-parameters-in-routes

The Rails Guides don't specify anthing about this.

Should I assume that this can not be done in rails? really?


you could just make two different routes instead

match 'posts', :to => 'posts#index'
match 'posts/:category', :to => 'posts#index'

The next route will not work as you intended it.

match 'posts(:filter[category])', :to => 'posts#index'

The :filter is just a place holder for either the first argument thats passed into the url helper or the value for the key :filter in a has that is passed in. Any expressions in the route string will not be evaluated.

I guess the answer to your question is that you cannot do this in rails. I would suggest to you though that you do this in another way. It is very helpful in rails to follow the convention and make things easier on yourself.

Looks like you are doing three things here. The base post routes

match 'posts', :to => 'posts#index'

A route that has the category nested in it. Most likely to give the user a better url

match 'posts/:category', :to => 'posts#index'

And a search url which can be the same as the first, or to make your action cleaner, a different one

match 'posts/search', :to => 'posts#search'

There is really no reason I can think of to complicate the routes in the way your are suggesting. A search query url doesn't look nice anyways so why bother handling two urls for searches. Just one will do.

You should definitely take a look at running

rake routes

as this will tell you exactly what you have defined in your routes file. You can also set up routing tests to ensure your custom routes are performing correctly.

Your example does not work (as you indicated)

# Case 2: nested hash params 
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts/old-school?filter[search]=the"

But what you should be looking for is this

posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts?filter[search]=the&filter[category]=old-school"

This is ok to do it this way.

If you want to keep posts/:category just use this for navigation only, not for search.

Hope that helps

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号