I currently have a comment model that posts under a micropost and both are displayed on the same page. The issue is that both are displayed on the same page and both are paginated and I am trying to go for the facebook approach to microposting. Here is the issue below:
The links for both pagination turns into this href="/users/2?page=2"
rather than href="/users/2/micropost?page=2"
or href="/users/2/comment?page=2"
. I am unsure how to go about solving this problem. Here are some of my code. All suggestions are much appreciated!
Micropost Render HTML
<table class="microposts">
<% if microposts.any? %>
<%= render microposts %>
<%= will_paginate microposts, :page_links => false %>
<% else %>
<div class="EmptyContainer"><span class='Empty'>Add a thread!</span></div>
<% end %>
</table>
Comment Section HTML
<div id='CommentContainer-<%= micropost.id%>' class='CommentContainer Condensed2'>
<div class='Comment'>
<%= render :partial => "comments/form", :locals => { :micropost => micropost } %>
</div>
<div id='comments'>
<% comments = micropost.comments.paginate(:per_page => 5, :page => params[:page]) %>
<%= render comments %>
<%= will_paginate comments, :class =>"pagination" %>
</div>
</div>
User Controller for the Show Page
def show
@user = User.find(params[:id])
@comment = Comment.find(params[:id])
@micropost = Micropost.new
@comment = Comment.new
@comment = @micropost.comments.build(params[:comment])
@comments = @micropost.comments.paginate(:page => params[:page], :per_page => 5)
@microposts = @user.microposts.order('created_at DESC').paginate(:per_page => 10, :page => params[:page])
respond_to do |format|
format.html
format.js
end
end
Problem lies within will_paginate way of creating urls for each page (it doesn't have anything to do with jQuery).
By design, will_paginate try its best to guess what's the base url for the page user is on (internally it's using controller/action to do that). That base url is then combined with any extra params passed to will_paginate helper using :params
and succesive page numbers.
For now (will_paginate 3.0.3), in order to overwrite this default behavior, you need to write your custom LinkRenderer class. Below there's example of such class - it makes use of new, extra option :base_link_url
that can be passed to will_paginate view helper. Passed string is then used as a base when creating pagination links. If :base_link_url
option is not passed, it will fallback to default behavior.
Put following class somewhere rails can find it on load (/lib for example, provided you've added /lib to your autoload paths in application.rb
):
# custom_link_renderer.rb
class CustomLinkRenderer < WillPaginate::ActionView::LinkRenderer
def prepare(collection, options, template)
@base_link_url = options.delete :base_link_url
@base_link_url_has_qs = @base_link_url.index('?') != nil if @base_link_url
super
end
protected
def url(page)
if @base_link_url.blank?
super
else
@base_url_params ||= begin
merge_optional_params(default_url_params)
end
url_params = @base_url_params.dup
add_current_page_param(url_params, page)
query_s = []
url_params.each_pair {|key,val| query_s.push("#{key}=#{val}")}
if query_s.size > 0
@base_link_url+(@base_link_url_has_qs ? '&' : '?')+query_s.join('&')
else
@base_link_url
end
end
end
end
Usage:
# in your view
will_paginate collection, :renderer => CustomLinkRenderer, :base_link_url => '/anything/you/want'
And now back to your case. By this time you probably see the solution - you can have two will_paginate widgets on one page with different base urls by passing different :base_link_url
options for those two.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With