6

私は自分のウェブサイト上の私のユーザメッセージングスレッド機能のために "acts_as_tree"プラグインを使用しています。私は選択されたメッセージを削除する方法を持っています。メッセージは実際には削除されません。 sender_status列またはrecipient_status列は、メッセージの送信者または受信者がどのユーザーかに応じて1に設定されます。ruby​​ on railで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はnilですが、他の理由でプライマリキー値に設定する必要があります。とにかく、tatメソッドの最後の行の最後に追加できるSQL文はありますか?行のIDがparent_idと等しくないメッセージだけを削除するようにするには?

実際のスレッド(メッセージテーブルの会話を参照するMessageThreadsテーブル)が削除されない限り、parent_id行が決して削除されないようにすることができます。

どうすればこの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これはそれが親メッセージであることを意味します。

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

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

を、その差を忘れないでください:Railsの4における昨今

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)を試しました。 0 – LondonGuy

+0

はい私は「最初に」逃した。このチェーンを複数の行ステートメントに分割して、エラーの発生場所を見つけることができますか?たとえば、親レコードを最初に取得し、次に 'children ....'を呼び出します。 –

+0

答えを更新しました。 delete_allはパラメータを受け入れません。 –

1

私は少し異なるアプローチを検討し、has_many関係は、例えば、それを:dependent => destroyを持ったモデルを持っているでしょう
User has_many :messages, :dependent => :destroy このようにして、あなたは「孤立した孤児のレコード」の問題を理解できません。

「これ以外のすべてのレコード」を考えるよりも、この方法を試してみます。
私は対処していないことがあるかどうかわかりませんが、これは説明されている問題を見つけるためのものです。

+0

メッセージモデルhas_one message_threadとmessage_threadモデルbelongs_toメッセージモデル。私がやったことで依存破壊をどのように実装するのか分かりません。私はマイクロポストとコメント機能でそれを使用しました。基本的には、メインのマイクロポストがすべて削除されたときにもそのコメントがあります。私はmessage_thread.messageを呼び出す場合、私は会話(メッセージテーブル内の親と子供)が立ち上がる参照message_threadをmessage.message_thread呼び出す場合message_thread belongs_toのメッセージが...親メッセージが起動するので、このメッセージシステムで、それは非常に複雑です。 – LondonGuy

+0

したがって、メッセージモデルで依存破壊を使用する場合、message_threadは削除されますが、親メッセージは削除されますが、すべての子が残るわけではありませんか?また、私はこれをもう一度行い、message_threadを削除しても、親メッセージを削除して子供を残しませんか?私はacts_as_treeがどのようにバックグラウンドで動作するかについてはあまりよく分かりません。 – LondonGuy

11

、あなたが行うことができます

  • destroy_all:関連オブジェクトが並んで破壊されていますこのオブジェクトはdestroyメソッドを呼び出すことによって呼び出されます。すべてのレコードをインスタンス化し、大規模なデータセットで、これは遅い
  • DELETE_ALLことができるよう、それらを一つずつ破壊:すべての関連するオブジェクトは、そのdestroyメソッドを呼び出すことなく、すぐに破壊されています。コールバックは呼び出されません。
+3

コールバックは 'delete_all'で起動されないので注意してください。あなたが依存関係を持っていても削除されることを期待している場合、それらは削除されません。代わりに 'destroy_all'を使います。 – cdownard

+1

それは本当です、それについて投稿するのを忘れてしまった、ありがとう! – igmarin

+1

これはおそらく答えになるはずです。 destroy_allへの更新を前提とします。 – brntsllvn

関連する問題