Chats: Add cascading delete on both referenced users.
authorlain <lain@soykaf.club>
Mon, 31 Aug 2020 14:48:17 +0000 (16:48 +0200)
committerlain <lain@soykaf.club>
Mon, 31 Aug 2020 14:48:17 +0000 (16:48 +0200)
Also remove the now-superfluous join in the chat controller,
which was only used to filter out these cases.

lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
priv/repo/migrations/20200831142509_chat_constraints.exs [new file with mode: 0644]
test/chat_test.exs

index 1f2e953f761cc4e915263946d13e9ad97a3cf97d..e8a1746d46a82d459dedc10799c58e92f4af2063 100644 (file)
@@ -149,9 +149,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
       from(c in Chat,
         where: c.user_id == ^user_id,
         where: c.recipient not in ^blocked_ap_ids,
-        order_by: [desc: c.updated_at],
-        inner_join: u in User,
-        on: u.ap_id == c.recipient
+        order_by: [desc: c.updated_at]
       )
       |> Repo.all()
 
diff --git a/priv/repo/migrations/20200831142509_chat_constraints.exs b/priv/repo/migrations/20200831142509_chat_constraints.exs
new file mode 100644 (file)
index 0000000..868a40a
--- /dev/null
@@ -0,0 +1,22 @@
+defmodule Pleroma.Repo.Migrations.ChatConstraints do
+  use Ecto.Migration
+
+  def change do
+    remove_orphans = """
+    delete from chats where not exists(select id from users where ap_id = chats.recipient);
+    """
+
+    execute(remove_orphans)
+
+    drop(constraint(:chats, "chats_user_id_fkey"))
+
+    alter table(:chats) do
+      modify(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
+
+      modify(
+        :recipient,
+        references(:users, column: :ap_id, type: :string, on_delete: :delete_all)
+      )
+    end
+  end
+end
index 332f2180a1d5e92dc0d837cc1b9f9da8ba7525e2..9e8a9ebf01abcca2ba80528c72ecef060e79afc8 100644 (file)
@@ -26,6 +26,28 @@ defmodule Pleroma.ChatTest do
       assert chat.id
     end
 
+    test "deleting the user deletes the chat" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
+
+      Repo.delete(user)
+
+      refute Chat.get_by_id(chat.id)
+    end
+
+    test "deleting the recipient deletes the chat" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
+
+      Repo.delete(other_user)
+
+      refute Chat.get_by_id(chat.id)
+    end
+
     test "it returns and bumps a chat for a user and recipient if it already exists" do
       user = insert(:user)
       other_user = insert(:user)