2012-03-05 3 views
6

J'ai actuellement un modèle de commentaire qui affiche sous un micropost et les deux sont affichés sur la même page. Le problème est que les deux sont affichés sur la même page et les deux sont paginés et j'essaie d'aller à l'approche facebook de micropostage. Voici le problème ci-dessous:Problème avec les liens de page de will_paginate

Les liens pour les deux pagination se transforme en href="https://stackoverflow.com/users/2?page=2" plutôt que href="https://stackoverflow.com/users/2/micropost?page=2" ou href="https://stackoverflow.com/users/2/comment?page=2". Je ne sais pas comment résoudre ce problème. Voici une partie de mon code. Toutes les suggestions sont très appréciées!

Micropost rendu 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> 

Commentaire 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> 

Contrôleur de l'utilisateur pour la page Afficher

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 

Répondre

8

Le problème réside dans la manière de créer des URLs pour chaque page (cela n'a rien à voir avec jQuery).

Par définition, will_paginate fait de son mieux pour deviner quelle est l'URL de base de l'utilisateur de la page (en interne, il utilise controller/action pour cela). Cette URL de base est ensuite combinée avec tous les paramètres supplémentaires passés à will_paginate helper en utilisant :params et les numéros de page successifs. Pour l'instant (will_paginate 3.0.3), afin d'écraser ce comportement par défaut, vous devez écrire votre classe LinkRenderer personnalisée. Ci-dessous, il y a un exemple d'une telle classe - il utilise une nouvelle option supplémentaire, :base_link_url, qui peut être passée à l'assistant d'affichage will_paginate. La chaîne passée est ensuite utilisée comme base lors de la création de liens de pagination. Si l'option :base_link_url n'est pas transmise, le comportement par défaut sera rétabli.

Mettre la classe suivante rails quelque part peut trouver de la charge (à vos chemins autoload/lib par exemple, à condition que vous avez ajouté/lib dans 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 

Utilisation:

# in your view 
will_paginate collection, :renderer => CustomLinkRenderer, :base_link_url => '/anything/you/want' 

Et maintenant retour à votre cas. A ce moment, vous voyez probablement la solution - vous pouvez avoir deux widgets will_paginate sur une page avec différentes URL de base en passant différentes options :base_link_url pour ces deux.

+0

Je suppose que pour 'collection' je le remplace par tout ce qui doit être paginé? Parce que sinon je reçois une erreur non définie – Kellogs

+0

aussi comment pourrais-je ajouter l'id de l'utilisateur dans le base_link_url? Parce que ces deux liens ne fonctionnent pas ': base_link_url =>"/users/<%= user.id%> ",' ': base_link_url =>"/users /: id ",' – Kellogs

+0

Oui, remplacez 'collection' par toute autre variable contenant des éléments à être paginé. Pour ce qui est de l'utilisation de l'option: base_link_url - ne pas passer la chaîne avec des espaces réservés comme dans route.rb - il suffit de passer le résultat de la méthode url helper. Par exemple si vous avez une route nommée "user_micropost" qui est tranlée à (par exemple) '/ user/2/micropost' alors' user_micropost_path (: id => 2) 'serait l'option que vous devez passer comme': base_link_url '. Tous les liens rendus obtiendraient alors l'URL comme:/user/2/micropost? Page = 1/user/2/micropost? Page = 2 et ainsi de suite. – WTK

Questions connexes