Delete the file from the database and from the upload folder too

hi there,

My code is making me able to delete the particular file from database but not deleting from the upload directory. And I can not find its solution. When i click on delete its deleting very neatly from table but not from the folder.
Here’s my code:

<span class="mr-10"><%= link "Delete", to: "#", phx_click: "delete", 
phx_value_id: file.id, data: [confirm: "Are you sure?"] %></span>
def handle_event("delete", %{"id" => id}, socket) do
    file = Files.get_file!(id)
    {:ok, _} = Files.delete_file(file)

    {:noreply, assign(socket, :files, list_files())}
  end

Hi!

Where is the code listing that uploads a file?

I would not really care that much and have a task delete files periodically…

But if You need to delete it on the spot, your solution seems ok.

Thanks for responding.
Through this code I’m also saving the file in the directory too. Other than by only saving in the table.

  def consume_file(socket, file) do
    consume_uploaded_entries(
      socket,
      :uploaded_files,
      fn %{path: path}, entry ->
        dest =
          Path.join([
            :code.priv_dir(:initium),
            "static",
            "/uploads/#{entry.uuid}.#{ext(entry)}"
          ])

        socket
        |> put_flash(:success, "File created successfully")

        File.cp!(path, dest)
      end
    )

    {:ok, file}
  end

You’re right. Code is well, working perfectly.
But I cannot find a functionality through which by deleting the file, it should not only delete in the database table(as it is happening perfectly) but also in the folder where its getting saved.

Please also post your File struct.

Here’s the file struct which is inserting my files in the database.

  def create_files(files \\ [], after_save \\ &{:ok, &1}) do
    allFiles =
      for file <- files do
        %File{}
        |> File.changeset(file)
        |> Repo.insert()
        |> after_save(after_save)
      end

    {:ok, files}
  end

And here’s the delete struct:

  def delete_file(%File{} = file) do
    Repo.delete(file)
  end

I think It can be possible to delete the file from the directory too by making changes into this one:

def handle_event("delete", %{"id" => id}, socket) do
    file = Files.get_file!(id)
    {:ok, _} = Files.delete_file(file)

    {:noreply, assign(socket, :files, list_files())}
  end

You’d need to call the File.rm functions (depending on the behavior you’re after).

I’m on my phone but you want to read through them and then use the ones you’re after. For instance, maybe you want to remove the folder altogether if it’s the last file, or not raise an error if it doesn’t exist, etc.

You can then have it looking for the same way you label your file’s path when you save it to the directory. That should do the trick provided everything else is good to go.

And yes, you need to specifically have this happen when you delete it (either handle event or other). I’d probably throw it in a job since it doesn’t necessarily have to happen right away and have it happen in 5 seconds or something.

Again, all that’s up to you and the needs of your app.

Edit for clarity— I quote the saving path because you need to make sure you call the correct path when looking for the file at time of delete/removal.

Hope it helps :heart:

1 Like

Thanks for providing the solution. Helped a lot :grinning_face_with_smiling_eyes:

1 Like