如何在rails上的ruby中实现show all comments功能?

时间:2012-04-17 17:31:37

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1

我正在为用户评论实施显示/隐藏功能。

在这里讨论:https://stackoverflow.com/a/10174194/439688

我的目标是: 1.将默认显示的注释限制为2。 2.有一个带有文本的范围,该文本说明该特定微博的总评论数量,当用户点击它时,它会展开并显示该微博的所有评论。我将使用Jquery / Ajax隐藏,显示,前置等。

第一个更改是限制向用户显示的注释数量,我通过在我的帮助程序中创建一个名为“comments”的方法实现了这一点,在这里我传入了注释所属的微博的id。

  def get_comments(micropost_id)
       Comment.limit(2).order("created_at DESC").where(:micropost_id => micropost_id)
  end

现在循环每个评论的每个循环只会显示最近的两条评论。

  <<% @microposts.each do |m| %>
    <% if m.poster_id.nil? %>
       <div class="postHolder">
        <nav class="micropostOptions">
         <ul class="postMenu">
           <li class="deletePost"><%= link_to content_tag(:span, "Delete post"), m, :method => :delete, :confirm => "Are you sure?", :title => m.content, :class => "message_delete", :remote => true %>
           </li>
           <li class="disableCommenting"><%= link_to content_tag(:span, "Pause commenting"), "2" %></li>
           <li class="blockCommenter"><%= link_to content_tag(:span, "Block commenter"), "3" %></li>
           <li class="openInNewWindow"><%= link_to content_tag(:span, "Open in new window"), "4" %></li>
           <li class="reportAbuse"><%= link_to content_tag(:span, "Report abuse"), "5" %></li>
         </ul>  
       </nav>


                <%= link_to image_tag(default_photo_for_current_user, :class => "poster_photo"), current_users_username %>

<div class="post_content">
    <div class="post_container">

        <div class="mainUserNameFontStyle"><%= link_to current_users_username.capitalize, current_users_username %> - <div class="post_time"> <%= time_ago_in_words(m.created_at) %> ago.</div> 
        </div>  
                  <%=  simple_format h(m.content) %> </div>
            <div class="commentsCount">
                <%= content_tag :span, pluralize(m.comments.count, 'comment'), :class => "view_all_comments" if m.comments.any? %>
            </div>
                        <% if m.comments.any? %>

                   <% comments(m.id).each do |comment| %>

                    <div class="comment_container">

                        <%= link_to image_tag(default_photo_for_commenter(comment), :class => "commenter_photo"), commenter(comment.user_id).username %>

                        <div class="commenter_content"> <div class="userNameFontStyle"><%= link_to commenter(comment.user_id).username.capitalize, commenter(comment.user_id).username %> - <%=  simple_format h(comment.content) %> </div>
                    </div><div class="comment_post_time"> <%= time_ago_in_words(comment.created_at) %> ago. </div>


                   </div>


                        <% end %>
                    <% end %>


                <% if logged_in? %>
                <%= form_for @comment, :remote => true do |f| %>
                <%= f.hidden_field :user_id, :value => current_user.id %>
                <%= f.hidden_field :micropost_id, :value => m.id %>
                <%= f.text_area :content, :placeholder => 'Post a comment...', :class => "comment_box", :rows => 0, :columns => 0 %>

        <div class="commentButtons">         
          <%= f.submit 'Post it', :class => "commentButton", :disable_with => "Post it" %>
           <div class="cancelButton"> Cancel </div>
        </div>   
                <% end %>

                <% end %>
    </div>


</div>

从这里开始,这让我感到困惑。我使用link_to稍微进一步,但后来决定我不想在浏览器状态栏中显示注释计数的url。这就是为什么我切换到使用span ..但现在做我想做的事情并不容易,因为我无法使用link_to / remote =&gt;现在是真的。

当用户点击评论计数范围时,如何进行ajax调用指向:

  def load_comments

  @load_comments = Comment.where(:micropost_id => params[:id])   
    respond_to do |format|
    format.js   { render :load_comments } 
    end

  end

我考虑过在users.js中添加一个click函数,但是如何将上面代码中每个循环中微博的参数传递给users.js?我不认为这是可能的。

我发表的所有评论都是通过ajax完成的,但因为我使用了这些表单,所以我只需要添加remote =&gt;就这么容易了。 true并创建一些js模板,并在ajax post成功时做点什么。

不确定我是否以正确的方式解决这个问题。我很感激来自更有经验的铁路程序员的帮助/建议。

亲切的问候

3 个答案:

答案 0 :(得分:2)

Rails partial

#Display基于本地传递给此部分

的所有评论

#最初将限制传递为2(或任何你想要的)。然后点击跨度通过限制为零。然后你可以检查limit是否为零,你可以在没有限制说明符的情况下查询模型。

<% @comments = Comment.custom_find(@your_params) %>
<% @comments.each do |comment|  %>
<%= comment.title %>
<% end %>

<强>的javascript / jquery的

function load_all_comments(id)
{
   new Ajax.Updater('show_comments',
      '<%=url_for(:controller => "your_controller", :action => "your_action")%>', {
       parameters: {'id':id },
       method:     'get',
       onSuccess: function(request){
       div_comments = document.getElementById("partial_comments_list");
       div_comments.innerHTML = request.responseText;

      }
   });
} // you can call this js function on span click. use jquery if you want. 

<强>控制器:

然后在your_controller的your_action中,不要忘记渲染部分

   render :partial => "show_comments", :layout => false

编辑:

you can even pass locals to your partial

 render :partial => "show_comments", :locals => {:post => @post}

每次根据您传递的当地人更新部分视图时使用此选项。

当然这只是一个例子而不是完整的代码/解决方案。

可能有更好的方法。但这对我来说很好。

答案 1 :(得分:1)

另一种选择是输出所有评论并隐藏您不想先显示的评论。 <div class="hidden_comments" style="display:none;"> a comment </div>

然后在点击跨度时只需要一些javascript来显示它们?

<script type="text/javascript">
   $("#span_id").click(function() {
      $('.hidden_comments').show();
});
</script>

如果您没有大量评论,这很有效。


如果你真的想按照自己的方式去做,我之前已经做过了,但它变得很乱。

将它放在你的application.js

$('.comment_span').live('click', function () {
    $.get(this.data_url, null, update_row, 'json');
    return false;
  });

你的跨度如下:

<span class="comment_span" data_url="http://website.com/resource/more_comments">
  show all comments
</span>

此示例将数据作为json返回,因此我使用update_row函数更新替换注释数据。

 function update_row(data, status) {
    $("#comments-table").append(data.html);
  };

这是我的控制器的样子:

  def more_comments
    @comments = Comments.all

    if @comments
      respond_to do |format|
        format.js {
                render :json => { 
                  :html => render_to_string(:partial => "comments"),
                  }.to_json
              }
      end
    end
  end

答案 2 :(得分:0)

您应该通过索引操作执行此操作。 将一个参数传递给它以确定是否要显示所有注释或仅显示当前集合(我将使用will_paginate来处理此问题。 我现在手机上的代码并没有太深入,但是这样的话:

class CommentsController < ApplicationController
  def index
    If params[:show_all] == "true"
      @comments = Comment.all
    else
      @comments = Comment.where(foo: bar).paginate(per_page: 2, page: params[:page])
    end
  end

然后你让它响应JavaScript并发送带有Ajax请求的页面参数