开发者

Ruby on Rails - Custom routing for review resource with index / show page and pagination

I'm stuck on a very tricky issue involving Rails 3 routes, and not good enough with routes to figure this one out on my own. I have a "Reviews" resource with only a "Show" and "Index" action. I am using the Friendly ID gem for slugged IDs, and I also have a nested comments resource, which allows people to comment on reviews.

resources :reviews, :only => [:index, :show] do
  resources :comments, :only => [:new, :create]
end 

So my paths thus far for the index page is simply 'reviews,' and something like 'reviews/the-matrix' for the show action. Simpl开发者_开发问答e enough so far.

Now first off, I hit a snag of sorts with the main index page. I have the will_paginate gem on the index page, and I am caching the page. Problem is, caching won't work when the path is something like /reviews?page=2, rather I need the path to be /reviews/2/ when going through pagination, so I added in the following above the previous review resource to make this work.

match 'reviews(/:page)' => 'reviews#index', :constraints => { :page => /[0-9]/ }

Why the constraint? Because my 'Show' resource route doesn't work because the above line - without the number constraint - ends up being a "catch-all" that interferes with the 'Show' route. Since the ID of the show action is always going to be words, while paginated pages on the index always has a number, this is why I did it this way.

But here's the thing, I don't want the 'Show' route to be simply 'reviews/the-matrix.' See, all reviews are categorized by type of thing being reviewed, so really I would like the 'Show' path to be something like 'reviews/movies/the-matrix,' or 'reviews/books/lord-of-the-rings.'

I would rather use the original reviews 'Show' path for additional category index pages, like 'reviews/books.' (Another reason for the constraint above.) But I am going to save that for another SO question, as I don't want to make this question too complicated.

So back to the previous question. Normally I imagine the above could be solved by a simple 'match' route (with route globbing?), except we have those nested comments in the Reviews resource. How do I go about making the 'Show' pages like the above, while retaining the Comments nested resource on Reviews?


No sweat (if this is what you mean).

match 'reviews(/:page)' => 'reviews#index', :constraints => {:page => /[0-9]+/}
match 'reviews/comments/:id' => 'comments#my_action', :constraints => {:id => /[0-9]+/}
match 'reviews/:path' => 'reviews#show', :constraints => {:path => /.+/}
  • Adding the constraint to the third instruction will allow you to use / in your :path. (It's true: using no constraints at all will not allow foo/bar to match this pattern.) (Alternative to the regex /.+/, you might wish /[a-zA-Z/]+/, but it shouldn't matter since the earlier paths already catch everything that shouldn't be a #show.)
  • Order matters. Keep these three in the order that they appear.
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜