Laravel 5.6 Image Upload, Save article slug as image name in database

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering File Uploads in Laravel: Saving Article Slugs as Image Names

As developers building dynamic applications with Laravel, handling file uploads efficiently and securely is a fundamental skill. When dealing with user-generated content like articles, ensuring that uploaded media is consistently named and properly stored is crucial for database integrity and application performance.

This post dives into a common challenge: how to upload an image while automatically deriving its filename from the article's slug, thereby linking the media directly to the content in your database. We will walk through the process using Laravel 5.6, focusing on robust file handling and adherence to best practices.

The Goal: Slug-Based File Naming

Our objective is simple yet powerful: If an article has a title like "My Awesome Post," we want the uploaded image file to be named my-awesome-post.jpg, and this exact slug should be stored in our articles table. This ensures that media management is centralized and predictable, which aligns perfectly with the principles of clean architecture promoted by Laravel.

Setting Up the Environment and Prerequisites

Before diving into the controller logic, ensure you have the necessary components configured:

  1. Slug Generation: You are already using a package like eloquent-sluggable to handle slug creation from the title. This is excellent; it ensures your database slugs are clean and URL-friendly.
  2. Storage Configuration: In modern Laravel, we generally use the configured disk (usually public or s3) rather than directly manipulating public_path(). For robust file management, always leverage the Storage facade when dealing with files, as this abstracts away the underlying filesystem operations.

Implementing the File Upload Logic in the Controller

Let's refine the logic within your ArticleController@store method to safely handle the file and rename it based on the article slug. We will focus on using Laravel’s built-in methods for moving files into the configured storage disk.

Refined Controller Implementation

Instead of manually constructing paths, we can use the storeAs method provided by the Illuminate\Http\Request object, which simplifies the process immensely.

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage; // Import the Storage facade

class ArticleController extends Controller
{
    public function store(Request $request)
    {
        $this->validate($request, [
            'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'title' => 'required',
            // ... other validations
        ]);

        $article = new Article();

        // 1. Generate the slug from the title
        $slug = str_slug($request->title);

        if ($request->hasFile('image')) {
            $imageFile = $request->file('image');
            
            // 2. Define the desired filename using the slug and original extension
            $imageName = $slug . '.' . $imageFile->getClientOriginalExtension();
            
            // 3. Store the file using the Storage facade
            // We store it in the 'public' disk, inside a folder named 'articles'
            $path = $imageFile->storeAs('articles', $imageName, 'public');

            // 4. Save the generated filename to the database
            $article->image_filename = $imageName; // Or store the path if you prefer
        }

        // Handle other fields
        $article->title = $request->get('title');
        $article->category_id = $request->get('category_id');
        $article->subtitle = $request->get('subtitle');
        $article->description = $request->get('description');

        $article->save();
        return back()->with('success', 'Your article has been added successfully.');
    }
}

Explanation of Changes and Best Practices

  1. Slug First: We calculate the $slug immediately from the title. This single variable becomes the foundation for all subsequent naming conventions.
  2. Leveraging storeAs(): Instead of manually dealing with public_path(), which can be brittle, we use $imageFile->storeAs('articles', $imageName, 'public');. This command handles the entire file movement and storage into the configured disk (in this case, the public disk) in one secure operation.
  3. Naming Convention: By constructing $imageName as $slug . '.' . $extension, we ensure that the resulting filename is clean, unique based on the content, and perfectly matches the slug requirement (article-1.jpg).
  4. Database Storage: We save the generated $imageName (e.g., article-1.jpg) into a dedicated column in the articles table. This design keeps your database clean while storing the human-readable filename reference.

Conclusion

Achieving dynamic, slug-based file naming for uploads is a common requirement in content management systems. By combining intelligent string manipulation (using slugs) with Laravel’s powerful and secure Storage facade, you can create file upload routines that are not only functional but also scalable and maintainable. Remember, focusing on clean code and leveraging the framework's tools—like those provided by Laravel—is key to developing robust applications. For more insights into structuring complex data relationships in Laravel, check out the official documentation at https://laravelcompany.com.