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 %>" οnclick="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 %>" οnclick="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,说明已经被自己删除掉了。