美文网首页ruby小白课程实战--宠物论坛
【Ruby on Rails全栈课程】4.6 评论功能实现(五)

【Ruby on Rails全栈课程】4.6 评论功能实现(五)

作者: 808cb3be8e58 | 来源:发表于2019-01-17 14:45 被阅读20次
1、在routes.rb文件中添加路径
get 'posts/delete_comment/:comment_id' => 'posts#delete_comment'
2、在posts_controller.rb文件中添加delete_comment方法
def delete_comment
end
3、在comment.rb文件中添加get_account_right方法,来获取当前用户是否有删除该评论的权利,有的话,在帖子详情页面中评论的后面显示删除按钮,没有的话不显示。
#判断当前用户是否有删除评论的权利
def get_account_right(current_user)
    #当没有用户登录,不显示删除链接
    if current_user.blank?
        boolean = false
    #当前用户的role字段为1、2时,代表是管理员、超级管理员,有删除评论的权利
    elsif current_user.role > 0
        boolean = true
    #如果是自己发布的评论,可以删除
    elsif current_user.id == self.account_id
        boolean = true
    else
        boolean = false
    end
    boolean
end

代码解析:

  • boolean
    倒数第二行代码boolean其实就是return boolean的意思,返回boolean的值。boolean = true代表有删除评论的权利,boolean = false代表没有删除评论的权利。用某个Comment对象调用get_account_right(current_user)方法,就会返回boolean的值。
4、修改partial文件views/posts/_show_posts.html.erb,在「回复」a标签的下面加入「删除」a标签(注意有两处位置)
<!--参考代码,无需粘贴-->
<!--<a id="reply<%= comment.id %>" onclick="outIn(<%=comment.id%>,<%=comment.id%>)">回复</a>-->
<!--添加「删除」a标签-->
<% if comment.get_account_right(@current_user) %>
  <a href="/posts/delete_comment/<%= comment.id %>">删除</a>
<% end %>
<!--参考代码,无需粘贴-->
<!--<a id="reply<%= re.id %>" onclick="outIn(<%= comment.id %>,<%=re.id%>)"> 回复</a>-->
<!--添加「删除」a标签-->
<% if re.get_account_right(@current_user) %>
  <a href="/posts/delete_comment/<%= re.id %>">删除</a>
<% end %>
5、分析错误

强调一下,修改之后的文件要记住保存哦~不然看不到效果。保存文件后,rails s启动项目,然后打开帖子详情页面,发布一条评论,再点击评论后面的删除链接可能会出现以下错误:

处理这个错误我们需要先来复习一下网页请求的路径:

根据请求链接/posts/delete_comment/1,在routes.rb文件中根据get 'posts/delete_comment/:comment_id' => 'posts#delete_comment’语句找到posts_controller里面的delete_comment方法。如果delete_comment方法里面没有render或者redirect_to语句指定接下来要去的views页面,系统会自动找posts文件夹下的delete_comment.html.erb文件。

所以,出现上面错误的原因,是因为delete_comment方法里面没有render或者redirect_to语句,并且系统也没有找到posts文件夹下的delete_comment.html.erb文件。所以碰到此类的错误ActionController::UnknownFormat有两种解决思路:

(1)给controller中的delete_comment方法添加render或者redirect_to语句
(2)给「删除」a标签加上data-remote=“true",实现ajax,这样系统如果找不到相应名字的模板,就会render到head :no_content(意思的不加载任何内容),还会停留在帖子详情页面。

因为此链接实现的目的是删除评论,「删除评论」是一个动作,不需要页面,删除动作完成之后回到帖子详情页面即可,所以我们先选择A解决方案,给controller中的delete_comment方法添加render或者redirect_to语句。下面来完善一下posts_controller里面的delete_comment方法。

6、完善posts_controller.rb文件delete_comment方法
def delete_comment
    comment_id = params[:comment_id]
    comment = Comment.find(comment_id)
    post_id = comment.post_id
    #comment表中status为1代表自己删除,为2代表管理员删除
    boolean = false
    if @current_user.id == comment.account_id
      comment.status = 1
    else @current_user.role > 0
      comment.status = 2
    end
    boolean = comment.save
    if boolean
        flash.notice = "删除成功"
    else
        flash.notice = "删除失败,请重新删除"
    end
    redirect_to "/posts/show_posts/#{post_id}"
end

重启项目重试,现在删除功能可以正常操作了。
但是有一个问题,这个问题需要多创建几条评论才能看出来,我们创建12条评论,然后到第二页,删除第二页的某条评论,你会发现页面会刷新,重新回到第一页,想要看删除后的效果,需要再点击到第二页才能看到,用户体验不好。
这是因为在controller的delete_comment方法中用redirect_to重定向到帖子详情页面(/posts/show_posts/#{post_id}),所以页面会刷新,想要实现删除第二页的评论,页面仍旧停留在第二页,并且能马上看到删除效果的功能,需要通过ajax来改善(即上面第5节分析错误中的解决方案2)。

7、改善删除效果

我们想要的效果是用户点击删除,还是停留在当前页面,并且显示出删除后的效果。这个效果我们需要通过ajaz和js来配合实现。与之前点赞功能的思路是一样的。

(1)修改partial文件views/posts/_show_posts.html.erb,将「删除」a标签加上ajax以及js方法。(注意有两处需要修改)
<!--原代码-->
<a href="/posts/delete_comment/<%= comment.id %>">删除</a>
<!--改为-->
<a data-remote="true" href="/posts/delete_comment/<%= comment.id %>" onclick="putDel()">删除</a>
<!--原代码-->
<a href="/posts/delete_comment/<%= re.id %>">删除</a>
<!--改为-->
<a data-remote="true" href="/posts/delete_comment/<%= re.id %>" onclick="putDel()">删除</a>
(2)编辑partial文件views/posts/_show_posts.html.erb,添加js方法putDel()
<script type="text/javascript">
function putDel(comment_id) {
  var content = document.getElementById("content_" + comment_id);
  var timeRight = document.getElementById("time_" + comment_id);
  content.innerHTML = "<span class='delete-content'>该评论已删除</span>";
  timeRight.style.display = "none";
 }
</script>

代码解析:
如果a标签中href元素与onclick元素同时存在,会先执行onclick,后执行href。所以当我们点击「删除」a标签时,会先执行js方法putDel(),将页面上的需要删除的评论的内容改为“该评论已删除”,其实现在还没有实际删除掉该评论,然后再执行href链接,找到对应的controller里面的delete_comment方法,在后台实际删掉该评论。

(3)修改posts_controller.rb文件中的delete_comment方法,将redirect_to和flash相关代码去掉。因为flash是下一次请求时才执行,没有redirect_to就没有flash的用武之地了。
def delete_comment
  comment_id = params[:comment_id]
  comment = Comment.find(comment_id)
  post_id = comment.post_id
  #comment表中status为1代表自己删除,为2代表管理员删除
  if @current_user.id == comment.account_id
    comment.status = 1
  else @current_user.role > 0
    comment.status = 2
  end
  comment.save
end

重启项目,我们再来看一下效果,点击删除按钮,不会刷新页面。被删除的评论会变为“该评论已删除”,然后停止项目到控制台(rails c)中,会看到该评论的status字段变成了1,说明已经被自己删除掉了。

相关文章

网友评论

    本文标题:【Ruby on Rails全栈课程】4.6 评论功能实现(五)

    本文链接:https://www.haomeiwen.com/subject/fjdvdqtx.html