Per User File Storage in Laravel

March 19th, 2025 • 2 minutes read time

Need to store files per user in Laravel? Let's discuss storing uploads for users in a separate directory to avoid collisions and keep our filesystem organised.

I'll start by mentioning that this solution isn't going to involve creating a custom filesystem adapter or anything more complicated than that. Why? From experience, when I've tried to automatically append a user ID onto the directory to store a file, my codebase has become more complex than needed.

So, let's take a look at the process of uploading files and storing each user's files separately.

Here's the basic upload form we're going to be using, along with the route:

Route::get('/', function (Request $request) {
    return view('upload');
});
<form action="/upload" method="post" enctype="multipart/form-data">
    @csrf

    <input type="file" name="file" id="file">
    <button type="submit">
        Upload
    </button>
</form>

Here's an example of how we'd usually store a file, choosing to add it to a files directory:

Route::post('/upload', function (Request $request) {
    $request->file('file')->store('files');

    return back();
});

This takes the file, generates a filename for us (like JRwtxrjK4cxoLa6U0en2GZxx8pqoQOflZpmttLRD.png) and stores it in the app/private directory.

As I mentioned earlier, doing anything other than appending on the ID makes our application wayy more complicated than it needs to be.

So, here's what I'd do:

Route::post('/upload', function (Request $request) {
    $request->file('file')->store('files/' . auth()->id());

    return back();
});

As you can see, the only change I've made is to add on the user's ID.

If you were storing the file in your database, you may do something like this:

Route::post('/upload', function (Request $request) {
    $request->user()->files()->create([
        'path' => $request->file('file')->store('files/' . auth()->id())
    ]);

    return back();
});

This would then fill the path column of your model with the full path to the file (e.g. files/1/file.png). That gives you the full path to the user-specific upload, so you're able to use this to download a file easily, like this:

Route::get('/files/{file}/download', function (File $file, Request $request) {
    return Storage::download($file->path);
});

This solution may seem a little underwhelming at first, but trust me — long term, it's not worth creating a custom filesystem to handle this stuff.

If you make it any more complex than this, something will get in the way later down the line!

If you found this article helpful, you'll love our practical screencasts.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first!