前情提要:
本篇將教學巢狀留言怎麼設定


安裝插件

巢狀留言軟刪除

如果今天已經幫留言設定好了軟刪除,但是想要把被刪除的留言顯示出來,並且顯示的是特定文字(留言已被使用者刪除),這樣要怎麼做呢?

看過官方文件後,只要這樣輸入,就可以把不管有沒有被刪除過的東西都抓出來

> YourModel.readonly.with_deleted
> 這樣可以把指定model的物件全部抓出來,不管有沒有被軟刪除過

讓我們來看看實際樣子:

# controllers/houses_controller.rb

class HousesController < ApplicationController
  before_action :find_house, only: [:show, :like, :dislike]
  

  def show
    @comment = @house.comments.new

    # 注意這段
    @comments = @house.comments.readonly.with_deleted.where("parent_id IS NULL OR parent_id = 0")
  end

  private
  def find_house
    @house = House.find(params[:id])
  end
end

可以看到 @comments 這邊,他把留言全部抓出來後,再補上後面那一段where,那一段的意思是,找到 root_houses,因為我們做的是巢狀留言,所以這邊先把沒有子留言的抓出來

接著我們把留言顯示出來

<!-- views/houses/show.html.erb -->

<section class="mt-36 mx-36">
  <div class="mb-6 bg-white rounded-lg shadow">
    
    <%# 渲染房子上方區塊 %>
    <%= render "card", house: @house %>
  
    <div class="w-full p-4 text-gray-600 focus-within:text-gray-400">            
      <%# 下面這邊是渲染留言表單出來順便會把兩個實體變數傳過去一個是房子實體變數傳過去變區域變數一個是把nil當作parent區域變數傳過去 <%>
      <%= render partial: 'comments/form', locals: { house: @house, parent: nil, url: comments_path(@house) } %>                
    </div>

    <div class="w-full p-10 mb-8 border-gray-100 border-y">
      <%= render @comments %>                            
    </div>
    <br>
     
  </div>

</section>

可以看到這一行:

<div class="w-full p-10 mb-8 border-gray-100 border-y">
  <%= render @comments %>                            
</div>

這一段可以渲染出這個畫面:

<!-- views/comments/_comments -->
<div class="my-2 text-sm text-gray-600">
  <span><%= comment.deleted_at ? "這則留言被該用戶刪除" : simple_format(comment.content) %></span>
</div>

這邊可以看到,我們先判斷留言的deleted_at是否有資料,如果今天有資料,就代表這則留言已經被刪除,如果沒有,就代表該留言還存在,因此我們寫一個判斷式,就是上面呈現的那樣

子留言的軟刪除

我們想要把子留言留在父留言的下方,因此我們這樣做:

<!-- views/comments/_comments -->
<div class="my-2 text-sm text-gray-600">
  <span><%= comment.deleted_at ? "這則留言被該用戶刪除" : simple_format(comment.content) %></span>
</div>

<div class="mt-10">
  <%= render comment.comments.readonly.with_deleted %>
</div>

這樣我們就可以把父留言、子留言已經被刪除的留言都顯示出來

實際例子

我們實際把東西印出來看看,我們先把正常的樣子印出來,一間房屋會有很多留言

> h = House.first
> h.comments
> 
> ------
> [#<Comment:0x00000001137940a0                                        
>   id: 71,                                                            
>   content: "fdsfdsf",                                                
>   user_id: 1,                                                        
>   house_id: 9,                                                       
>   created_at: Tue, 02 May 2023 15:29:16.264570000 CST +08:00,        
>   updated_at: Tue, 02 May 2023 15:29:16.264570000 CST +08:00,        
>   parent_id: 68,                                                     
>   deleted_at: nil>,                                                  
>  #<Comment:0x000000011378ff00                                        
>   id: 66,                                                            
>   content: "讚讚好棒",                                               
>   user_id: 2,                                                        
>   house_id: 9,
>   created_at: Thu, 27 Apr 2023 17:34:24.227720000 CST +08:00,
>   updated_at: Thu, 27 Apr 2023 17:34:24.227720000 CST +08:00,
>   parent_id: nil,
>   deleted_at: nil>,
>  #<Comment:0x000000011378fd98
>   id: 67,
>   content: "我好爛",
>   user_id: 2,
>   house_id: 9,
>   created_at: Thu, 27 Apr 2023 17:34:29.893655000 CST +08:00,
>   updated_at: Thu, 27 Apr 2023 17:34:29.893655000 CST +08:00,
>   parent_id: 66,
>   deleted_at: nil>,
>  #<Comment:0x000000011378fc30
>   id: 68,
>   content: "我\n好\n棒",
>   user_id: 2,
>   house_id: 9,
>   created_at: Fri, 28 Apr 2023 16:47:42.343017000 CST +08:00,
>   updated_at: Fri, 28 Apr 2023 16:47:42.343017000 CST +08:00,
>   parent_id: nil,
>   deleted_at: nil>] 

不過上面那樣輸入指令,只會把沒被軟刪除的留言列出來,我們來看看用 readonly.with_deleted 這個指令:


> h = House.first
> h.comments.readonly.with_deleted

------
> [#<Comment:0x0000000114d670f8                                                                             
>   id: 71,                                                                                                 
>   content: "fdsfdsf",                                                                                     
>   user_id: 1,                                                                                             
>   house_id: 9,                                                                                            
>   created_at: Tue, 02 May 2023 15:29:16.264570000 CST +08:00,                                             
>   updated_at: Tue, 02 May 2023 15:29:16.264570000 CST +08:00,                                             
>   parent_id: 68,                                                                                          
>   deleted_at: nil>,                                                                                       
>  #<Comment:0x0000000114d66f90                                                                             
>   id: 65,                                                                                                 
>   content: "讚讚讚",                                                                                      
>   user_id: 2,                                                                                             
>   house_id: 9,
>   created_at: Thu, 27 Apr 2023 15:01:26.975122000 CST +08:00,
>   updated_at: Thu, 27 Apr 2023 15:03:00.691882000 CST +08:00,
>   parent_id: 64,
>   deleted_at: Thu, 27 Apr 2023 15:03:00.691850000 CST +08:00>,
>  #<Comment:0x0000000114d66e28
>   id: 64,
>   content: "哇哇哇",
>   user_id: 2,
>   house_id: 9,
>   created_at: Thu, 27 Apr 2023 15:01:21.818236000 CST +08:00,
>   updated_at: Thu, 27 Apr 2023 15:03:03.701301000 CST +08:00,
>   parent_id: nil,
>   deleted_at: Thu, 27 Apr 2023 15:03:03.701293000 CST +08:00>,
>  #<Comment:0x0000000114d66cc0
>   id: 66,
>   content: "讚讚好棒",
>   user_id: 2,
>   house_id: 9,
>   created_at: Thu, 27 Apr 2023 17:34:24.227720000 CST +08:00,
>   updated_at: Thu, 27 Apr 2023 17:34:24.227720000 CST +08:00,
>   parent_id: nil,
>   deleted_at: nil>,
>  #<Comment:0x0000000114d66b58
>   id: 67,
>   content: "我好爛",
>   user_id: 2,
>   house_id: 9,
>   created_at: Thu, 27 Apr 2023 17:34:29.893655000 CST +08:00,
>   updated_at: Thu, 27 Apr 2023 17:34:29.893655000 CST +08:00,
>   parent_id: 66,
>   deleted_at: nil>,
>  #<Comment:0x0000000114d669f0
>   id: 68,
>   content: "我\n好\n棒",
>   user_id: 2,
>   house_id: 9,
>   created_at: Fri, 28 Apr 2023 16:47:42.343017000 CST +08:00,
>   updated_at: Fri, 28 Apr 2023 16:47:42.343017000 CST +08:00,
>   parent_id: nil,
>   deleted_at: nil>,
>  #<Comment:0x0000000114d66888
>   id: 70,
>   content: "你好棒",
>   user_id: 1,
>   house_id: 9,
>   created_at: Tue, 02 May 2023 15:27:43.352346000 CST +08:00,
>   updated_at: Tue, 02 May 2023 15:28:23.829312000 CST +08:00,
>   parent_id: 68,
>   deleted_at: Tue, 02 May 2023 15:28:23.829200000 CST +08:00>]

上面輸入後,可以看到我們把所有留言都抓到了, deleted_at 有數據的留言,就是代表該留言在該時間點被刪掉。