How to create simple CRUD in Laravel?
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:
-
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
-
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
, andDB_PASSWORD
) to match your database setup. -
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 theapp/Models
directory and a corresponding migration file namedYYYY_MM_DD_HHMMSS_create_posts_table.php
in thedatabase/migrations
directory.Open the migration file and modify the
up
method to define the schema for yourposts
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
-
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 theapp/Http/Controllers
directory. -
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!'); }
-
Create Blade Templates (Views):
-
In Laravel, Blade templates are conventionally organized within the
resources/views
directory. While Laravel doesn't enforce a specific structure, creating folders withinviews
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 namedposts
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 createdposts
folder.resources/views/ posts/ create.blade.php edit.blade.php index.blade.php ...other folders or views...
-
Bash
-
7. Create Blade Templates (Views) :
This command creates several Blade template files within the
resources/views/posts
directory: -
php artisan make:view posts/create
php artisan make:view posts/index
php artisan make:view posts/edit
index.blade.php
: This view will display a list of all posts.create.blade.php
: This view will present the form for creating a new post.edit.blade.php
: This view will show the form for editing an existing post.-
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:
- The view extends a layout file (
layouts.app
) if you have one for basic page structure. - It checks for a
success
session message and displays an alert if present. - A table displays post titles, limited content snippets (
Str::limit
), and edit/delete buttons. - Edit buttons use route model binding to pass the post ID.
- The delete form includes CSRF protection and the
@method('DELETE')
directive. -
Create similar views for
create.blade.php
andedit.blade.php
using HTML forms and appropriate validation rules: 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 thearticles.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')
andold('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
forstore
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
-
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.
-
9. Run the Application:
Start the Laravel development server by running:
Bash
-
php artisan serve
Open http://localhost:8000 (or your configured port) in your browser to access the application.
10. Test Your CRUD Functionality:
- Visit
http://localhost:8000/posts
to see the list of posts (initially empty). - Click "Create New Post" to access the creation form.
- Fill out the form and submit it to create a new post.
- Visit
http://localhost:8000/posts
again to see the newly created post listed. - Click the "Edit" button for a post to edit its details.
- Click the "Delete" button (with confirmation) to remove a post.
-
Additional Considerations:
- Validation: Implement validation rules for form submissions using Laravel's validation classes to ensure data integrity.
- Authorization: Consider implementing authorization checks (e.g., using Laravel's policies) to restrict access to CRUD operations based on user roles.
- Pagination: If you expect a large number of posts, implement pagination to display them in manageable chunks.
- Error Handling: Handle potential errors during CRUD operations (e.g., database errors, validation errors) to provide informative messages to the user.
-
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.