Elixir/Phoenix Ecto:更新无限嵌套递归关联中的所有子级

问题描述 投票:0回答:1

我有这些桌子

folders
files

文件夹

schema "folders" do
  field :name, :string
  field :archived, :boolean

  belongs_to :folder, Folder
  has_many :folders, Folder
  has_many :files, File
end

文件

schema "files" do
  field :name, :string
  field :archived, :boolean

  belongs_to :folder, Folder
end

当我们软删除文件夹和文件时,会使用

archived
列。

父文件夹可以有无限的子文件夹和文件。

FolderA
 |-file1
 |-file2
 |-folder_b
    |-file1
    |-folder_c
       |-file1
       |-folder_d
         ...
         # NO_LIMIT

现在,我需要做的是,如果我软删除

FolderA
,所有子文件夹和文件也应该被软删除(将
archived
值更新为
true
)。

如何在 Ecto 甚至 PostgreSQL 中完成此操作?

postgresql elixir phoenix-framework ecto
1个回答
0
投票

我修改了 Ecto 文档中的示例(https://hexdocs.pm/ecto/Ecto.Query.html#with_cte/3-recursive-ctes)以满足您的需求:

  def soft_delete_tree_for_folder(root_folder) do
    root_id = root_folder.id
    folder_tree_initial_query = where(Folder, [f], f.id == ^root_id)
    folder_tree_recursion_query = join(Folder, :inner, [f], fo in "folders_tree", on: fo.folder_id == f.id)
    folder_tree_query = union_all(folder_tree_initial_query, ^folder_tree_recursion_query)

    Folder
    |> recursive_ctes(true)
    |> with_cte("folders_tree", as: ^folder_tree_query)
    |> join(:left, [f], fo in "folders_tree", on: fo.id == f.folder_id)
    |> group_by([f], f.id)
    |> select([f, fo], f)
    |> Repo.soft_delete_all()
  end
© www.soinside.com 2019 - 2024. All rights reserved.