6

我在我的網站上爲我的用戶消息傳遞線程功能使用了「acts_as_tree」插件。我有一種方法可以刪除選定的消息。這些消息實際上並未被刪除。他們的sender_status或recipient_status列設置爲1,具體取決於用戶是消息的發件人還是收件人。我將如何destroy_all或delete_all記錄除了在軌道上的紅寶石?

無論如何,如果兩個用戶都將這些狀態設置爲1,那麼最後一行確保消息行完全從數據庫中移出。現在,只要它不是被刪除的父消息就沒有問題。如果父消息被刪除,那麼沒有被選擇刪除的孩子將不能再被訪問。

這裏是方法:

 def delete_all_users_selected_messages(message_ids, user_id, parent_id) 
      Message.where(:id => message_ids, :sender_id => user_id).update_all(:sender_status => 1) 
      Message.where(:id => message_ids, :recipient_id => user_id).update_all(:recipient_status => 1) 
      Message.delete_all(:sender_status => 1, :recipient_status => 1, :parent_id => parent_id).where("id != ?", parent_id) 
     end 

這是很明顯我想要做的事。我需要忽略父項。因此,在主鍵等於parent_id的情況下,意味着該行是父項(通常parent_id爲零,但我需要將其設置爲主鍵值,這是因爲其他原因,長話短說並不重要)。無論如何,有一個SQL語句可以添加到tat方法最後一行的結尾嗎?爲了確保它只刪除行的id不等於parent_id的消息?

我可以安排parent_id行永遠不被允許刪除,除非實際線程(引用消息表對話的MessageThreads表)被刪除。

無論如何我可以做到這一點,所以當該delete_all方法運行時,這個父行會被忽略?

親切的問候

回答

2

這對我來說最終是有效的。

Message.where('id != ? AND parent_id = ?', parent_id, parent_id).where(:sender_status => 1, :recipient_status => 1).delete_all 

基本上會返回除了id == parent_id之外的那個特定對話的所有消息。哪裏有id == parent_id,這意味着它是一條父消息。

2

爲什麼不使用父記錄的關聯,像這樣?

Message.where(:id => parent_id).first 
    .children.where(:sender_status => 1, :recipient_status => 1) 
    .delete_all 
+0

得到未定義的方法的孩子,所以我試着Message.where(:id => parent_id).first.children.delete_all(:sender_status => 1,:recipient_status => 1)..然後得到錯誤數量的參數1爲0 – LondonGuy 2012-02-22 00:15:00

+0

對不起,我錯過了'第一個'。你能把這條鏈分成多行語句,以便我們可以找到錯誤發生的地方嗎?例如先獲取父記錄,然後調用'children ....'。 – 2012-02-22 00:20:47

+0

更新了答案。 delete_all不接受參數。 – 2012-02-22 00:26:19

1

我會考慮一個稍微不同的方法,有具有has_many關係模型有:dependent => destroy有了它,例如
User has_many :messages, :dependent => :destroy 這樣你就不會得到你描述的'懸掛孤兒記錄'問題。

我會試着用這種方式來處理它,而不是想'除了'以外的所有記錄。
我不知道是否有什麼東西我沒有解決,但這是什麼來找到所述的問題。

+0

消息模型has_one message_thread和message_thread模型belongs_to消息模型。我不知道如何用我所做的來實現相關的摧毀。我用我的微博和評論功能。基本上,當主微博被刪除時,所有的評論也是如此。有了這個消息系統,它非常複雜,因爲message_thread belongs_to消息..如果我調用message_thread.message,那麼如果我調用message.message_thread,則會引發父消息引用對話(消息表中的父項和子項)的message_thread出現。 – LondonGuy 2012-02-22 08:01:52

+0

因此,如果我要在消息模型中使用依賴銷燬,message_thread將被刪除,父消息將被刪除,但不會留下所有的子項?另外如果我這樣做了另一種方式,並刪除了一個message_thread不會只是刪除父消息,並離開孩子?我不太確定acts_as_tree如何在後臺運行。 – LondonGuy 2012-02-22 08:02:19

11

如今在Rails中4,你可以這樣做:

Model.where.not(attr: "something").delete_all 

Model.where.not(attr: "something").destroy_all 

而且不要忘了區別:

  • destroy_all:關聯對象一起銷燬這個對象通過調用它們的destroy方法。實例化所有記錄並逐個銷燬它們,所以對於大數據集,這可能會很慢
  • delete_all:所有關聯的對象都會立即銷燬,而不會調用它們的destroy方法。回調不被調用。
+3

需要注意的是,回調不會在'delete_all'上被觸發,所以如果你有依賴關係,你也希望被刪除,他們不會。使用'destroy_all'代替那個需要。 – cdownard 2015-01-22 06:31:10

+1

這是真的,忘了張貼,謝謝! – igmarin 2015-03-23 19:43:24

+1

這應該可能是答案。假設更新爲destroy_all。 – brntsllvn 2015-06-19 20:27:37