How to create simple CRUD in Laravel?

How to create simple CRUD in Laravel?



Laravel 4 months ago

This tutorial guides you step-by-step through creating a simple and complete CRUD (Create, Read, Update, Delete) application using Laravel. We will cover key concepts and best practices for effective implementation.

Prerequisites:

  • PHP (version 7.4 or higher) installed on your system. You can check your PHP version by running php -v in your terminal.
  • Composer (a dependency manager for PHP) installed. You can download it from https://getcomposer.org/.
  • A basic understanding of Laravel concepts like models, controllers, views, and migrations.

Steps:

  1. Create a New Laravel Project:

    Open your terminal and navigate to your desired project directory. Then, run the following command to create a new Laravel project named laravel-crud:

    Bash

    composer create-project laravel/laravel laravel-crud
    
  2. Configure Database Connection:

    Edit the .env file located in the project's root directory. Update the database credentials (DB_CONNECTION, DB_HOST, DB_DATABASE, DB_USERNAME, and DB_PASSWORD) to match your database setup.

  3. Create a Model and Migration:

    We'll create a model for our CRUD application, let's call it Post. In your terminal, run:

    Bash

    php artisan make:model Post -m
    

    This command creates a Post.php file in the app/Models directory and a corresponding migration file named YYYY_MM_DD_HHMMSS_create_posts_table.php in the database/migrations directory.

    Open the migration file and modify the up method to define the schema for your posts table. Here's an example:

    PHP

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }
    

    Run the migration to create the table in your database:

    Bash

    php artisan migrate
    
  4. Create a Controller:

    Generate a controller named PostController using the Artisan command:

    Bash

    php artisan make:controller PostController --resource
    

    This creates a PostController.php file in the app/Http/Controllers directory.

  5. Implement CRUD Operations in the Controller:

    Open the PostController.php file and customize the methods for CRUD functionality. Here's a breakdown with explanations:

    • Index (Read): Retrieves a list of posts and renders the index view.

    PHP

    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }
    
    • Create (Create): Shows the form for creating a new post and handles form submission.

    PHP

    public function create()
    {
        return view('posts.create');
    }
    
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);
    
        $post = Post::create($validatedData);
    
        return redirect('/posts')->with('success', 'Post created successfully!');
    }
    
    • Edit (Update): Fetches the post for editing and displays the edit form. Handles form submission to update the post.

    PHP

    public function edit(Post $post) // Route model binding
    {
        return view('posts.edit', compact('post'));
    }
    
    public function update(Request $request, Post $post) // Route model binding
    {
        $validatedData = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);
    
        $post->update($validatedData);
    
        return redirect('/posts')->with('success', 'Post updated successfully!');
    }
    
    • Destroy (Delete): Deletes the specified post.

    PHP

    public function destroy(Post $post) // Route model binding
    {
        $post->delete();
    
        return redirect('/posts')->with('success', 'Post deleted successfully!');
    }
    
  6. Create Blade Templates (Views):

  7.  

     

     

    In Laravel, Blade templates are conventionally organized within the resources/views directory. While Laravel doesn't enforce a specific structure, creating folders within views is a good practice for better organization and maintainability of your project. Here's how to achieve this:

    1. Creating Folders:

    Use your preferred file management tool or terminal commands to create folders within resources/views. For example, to create a folder named posts for your article-related views:

    Bash

    mkdir resources/views/posts
    

    2. Organize Your Views:

    Move your existing Blade template files (e.g., index.blade.php, create.blade.php, edit.blade.php)  into the newly created posts folder.

    resources/views/
        posts/
            create.blade.php
            edit.blade.php
            index.blade.php
        ...other folders or views...
    

     

  8.  

     

    Generate Blade templates for displaying and managing posts:

     

    Bash

  9. 7. Create Blade Templates (Views) :

    This command creates several Blade template files within the resources/views/posts directory:

  10.  

    php artisan make:view posts/create
    php artisan make:view posts/index
    php artisan make:view posts/edit
  11. index.blade.php: This view will display a list of all posts.
  12. create.blade.php: This view will present the form for creating a new post.
  13. edit.blade.php: This view will show the form for editing an existing post.
  14. Open index.blade.php and add the following code to display a table of posts with title, content, and edit/delete buttons:

    HTML

    @extends('layouts.app') @section('content')
        <h1>Posts</h1>
    
        @if (session('success'))
            <div class="alert alert-success" role="alert">
                {{ session('success') }}
            </div>
        @endif
    
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Title</th>
                    <th>Content</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                @foreach ($posts as $post)
                <tr>
                    <td>{{ $post->title }}</td>
                    <td>{{ Str::limit($post->content, 50) }}</td> <td>
                        <a href="{{ route('posts.edit', $post) }}" class="btn btn-sm btn-primary">Edit</a>
                        <form action="{{ route('posts.destroy', $post) }}" method="POST" style="display: inline-block">
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-sm btn-danger">Delete</button>
                        </form>
                    </td>
                </tr>
                @endforeach
            </tbody>
        </table>
    
        <a href="{{ route('posts.create') }}" class="btn btn-primary">Create New Post</a>
    @endsection
    

    Explanation:

  15. The view extends a layout file (layouts.app) if you have one for basic page structure.
  16. It checks for a success session message and displays an alert if present.
  17. A table displays post titles, limited content snippets (Str::limit), and edit/delete buttons.
  18. Edit buttons use route model binding to pass the post ID.
  19. The delete form includes CSRF protection and the @method('DELETE') directive.
  20. Create similar views for create.blade.php and edit.blade.php using HTML forms and appropriate validation rules:

  21. create.blade.php: Include form fields for title and content with validation rules.

create.blade.php:

HTML

@extends('layouts.app')

@section('content')
<h1>Create New Article</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<form method="POST" action="{{ route('articles.store') }}">
    @csrf

    <div class="form-group">
        <label for="titre">Title</label>
        <input type="text" class="form-control @error('titre') is-invalid @enderror" id="titre" name="titre" value="{{ old('titre') }}">
        @error('titre')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>

    <div class="form-group">
        <label for="contenu">Content</label>
        <textarea class="form-control @error('contenu') is-invalid @enderror" id="contenu" name="contenu" rows="5">{{ old('contenu') }}</textarea>
        @error('contenu')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>

    <button type="submit" class="btn btn-primary">Create</button>
</form>
@endsection

Explanation:

  • Extends your layouts.app for overall page structure.
  • Displays a heading "Create New Article".
  • Checks for validation errors and displays them in an alert box if any.
  • Includes a form with CSRF protection (@csrf) and POST method to submit data to the articles.store route.
  • Uses Blade directives for form elements and error handling:
    • @error directive checks for specific validation errors and displays them with appropriate Bootstrap classes for styling.
    • old('titre') and old('contenu') keep form data populated in case of validation errors, preventing users from re-entering information.
  • Includes fields for title (titre) and content (contenu).
  • Validates the form input using Laravel's validation classes. You'll need to add corresponding rules in the ArticleController for store method.
  • Submit button with the text "Create".

edit.blade.php:

HTML

@extends('layouts.app')

@section('content')
<h1>Edit Article</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<form method="POST" action="{{ route('articles.update', $article->id) }}">
    @csrf
    @method('PUT') <div class="form-group">
        <label for="titre">Title</label>
        <input type="text" class="form-control @error('titre') is-invalid @enderror" id="titre" name="titre" value="{{ $article->titre }}">
        @error('titre')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>

    <div class="form-group">
        <label for="contenu">Content</label>
        <textarea class="form-control @error('contenu') is-invalid @enderror" id="contenu" name="contenu" rows="5">{{ $article->contenu }}</textarea>
        @error('contenu')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>

    <button type="submit" class="btn btn-primary">Update</button>
</form>
@endsection
  1. 8. Define Routes:

    Open the routes/web.php file and add routes for the CRUD operations:

    PHP

    Route::resource('posts', PostController::class);
    

    This single line handles all CRUD routes using resource routing.

  2. 9. Run the Application:

    Start the Laravel development server by running:

    Bash

  3. php artisan serve
    

    Open http://localhost:8000 (or your configured port) in your browser to access the application.

    10. Test Your CRUD Functionality:

  4. Visit http://localhost:8000/posts to see the list of posts (initially empty).
  5. Click "Create New Post" to access the creation form.
  6. Fill out the form and submit it to create a new post.
  7. Visit http://localhost:8000/posts again to see the newly created post listed.
  8. Click the "Edit" button for a post to edit its details.
  9. Click the "Delete" button (with confirmation) to remove a post.
  10. Additional Considerations:

  11. Validation: Implement validation rules for form submissions using Laravel's validation classes to ensure data integrity.
  12. Authorization: Consider implementing authorization checks (e.g., using Laravel's policies) to restrict access to CRUD operations based on user roles.
  13. Pagination: If you expect a large number of posts, implement pagination to display them in manageable chunks.
  14. Error Handling: Handle potential errors during CRUD operations (e.g., database errors, validation errors) to provide informative messages to the user.
  15. By following these steps and incorporating the best practices mentioned, you'll have a robust and scalable Laravel CRUD application as a foundation for your future web development projects.