will paginate, nested routes, ruby, rails
I'm trying to get will paginate to link to my nested route instead of the regular posts variable. I know I'm supposed to pass some params to paginate but I don't know how to pass them.
Basically there is an array stored in @posts
and the other param paginate has access to is category_id
.
The nested route is /category/1/posts
but hitting next and previous on will paginate returns a url like this posts?page=1&category_id=7
.
<%= will_paginate @most_recent_posts "What do I do here?" %>
This is the result of Yannis's answer:
In your controller you can do:
@posts = @category.posts.paginate
And in your view:
<%= will_paginate(@post) %>
Doing this comes up with the following URL
posts?page=2&post_category_id=athlete_management
routes.rb #there are more routes but these are the relevant ones
map.resources :posts
map.resources :post_categories, :has_many => :posts
solution
map.resources :post_categories do |post_category|
post_category.resources :posts
end
map.resources :开发者_JS百科posts
Had to declare the resource after the block
Thanks stephen!
Parachuting in here on this old question because I encountered the same issue.
I had pretty much exactly the same problem. I followed the responders' advice that something funky was going on with the routes. I dug into the routes and found (translated to suit your situation):
resources :posts
resources :categories do
resources :posts
end
This made it so that calling category_posts_path
returned (as expected) /category/1/posts
.
However, it's of pivotal importance to realize that will_paginate
calls something that resembles url_for
, which works "backwards" from the routes to find the first route that matches the parameters.
Since resources :posts
appears above the nested route, it sees that that one satisfies the requirements and just inserts category_id=1
was a query string.
The reason it worked "out of the box" for everyone else was because they didn't have the nested resource separately listed as a standalone resource.
Remove that and you should be fine!
In your controller you can do:
@posts = @category.posts.paginate
And in your view:
<%= will_paginate(@post) %>
Okay, so it's not clear from the question exactly, but I'm assuming that you are trying to go from a root-level URL like /posts
into pages for specific categories like /category/1/posts
.
The reason I assume this is because I have nested routes (in a namespace even) where will_paginate works fine without any special params. If that is not the case then there is probably something else funky going on with your routes and more information will be needed to debug.
However I can at least explain how will_paginate works. When it's generating the page URLs it calls url_for
with existing params plus the specific page needed. Therefore, if you already have a bunch of params set, it should preserve them, including ones that are part of the path itself. Fortunately it also allows you to pass additional params to merge in with the (surprise!) :params
parameter to will_paginate.
Now assuming you have the nested routes set up properly, /category/1/posts
can be generated by:
url_for(:controller => 'posts',
:category_id => '1')
But if you are on the page /posts
then the params will only be:
{:controller => 'posts'}
So you need to pass the category_id to will_paginate like so:
<%= will_paginate @posts, :params => {:category_id => @posts.first.category_id} %>
If this doesn't work, then I suspect something wrong with your routes. Try putting a debug statement in the template and calling url_for
with different permutations of the params. Remember that the route definition order matters and could be creating conflicts.
精彩评论