WEB ‐ Laravel ‐ CRUD APP (Part 2) - johnverz22/appdev-lessons GitHub Wiki

Laravel Beginner-Friendly Guide

1. Introduction to Laravel

What is Laravel?

Laravel is a PHP framework designed to make web development easier by providing built-in tools for authentication, routing, and database management. It follows the Model-View-Controller (MVC) architecture, ensuring clean code organization.

Key Features:

  • Elegant syntax and built-in functions
  • Blade templating engine for easy UI rendering
  • Eloquent ORM for database operations
  • Middleware for request filtering
  • Authentication and authorization tools

Installing Laravel via Composer

To install Laravel, follow these steps:

  1. Install Composer if you haven’t already.
  2. Open your terminal and run:
    composer create-project laravel/laravel my_project
  3. Navigate to the project folder:
    cd my_project
  4. Start the development server:
    php artisan serve
  5. Open http://127.0.0.1:8000/ in your browser to see the Laravel welcome page.

Understanding Laravel Directory Structure

Laravel has a structured directory system:

  • app/: Contains core logic like models, controllers, and middleware.
  • bootstrap/: Loads the framework and initializes the application.
  • config/: Stores configuration files.
  • database/: Contains migrations, seeders, and factories.
  • public/: Stores entry files like index.php and assets like CSS and JS.
  • resources/: Holds views (Blade templates) and raw assets.
  • routes/: Defines web, API, and console routes.
  • storage/: Stores logs, cached views, and file uploads.
  • tests/: Contains test files.
  • vendor/: Houses installed Composer dependencies.

2. Laravel Basics

Routing and Controllers

Routes define application URLs and their associated logic. They are stored in routes/web.php for web applications.

Example Route:

Route::get('/welcome', function () {
    return view('welcome');
});

Using Controllers:

To create a controller, run:

php artisan make:controller HomeController

Then, define methods inside the controller and assign them to routes:

Route::get('/home', [HomeController::class, 'index']);

Request Lifecycle in Laravel

  1. Request: The user makes a request (e.g., visiting a URL).
  2. Routing: Laravel determines which route matches the request.
  3. Middleware: Filters the request (e.g., authentication checks).
  4. Controller: Executes business logic and returns a response.
  5. View: Data is rendered into HTML using Blade.
  6. Response: The final output is sent to the user.

Configuring Environment Variables (.env file)

Laravel uses a .env file to manage environment-specific settings.

Example .env Configuration:

APP_NAME=LaravelApp
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=root
DB_PASSWORD=
  • Update .env when deploying: Ensure APP_ENV=production and APP_DEBUG=false for security.
  • Clear cache after changes:
    php artisan config:clear

3. Database & Eloquent ORM

Setting up a Database (MySQL)

Laravel supports multiple databases, but MySQL is commonly used. To configure MySQL:

  1. Install MySQL and ensure it is running.
  2. Update the .env file with database credentials:
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_db
    DB_USERNAME=root
    DB_PASSWORD=
  3. Run migrations to create necessary tables:
    php artisan migrate

Understanding Migrations

Migrations allow version control for the database schema.

  • Create a migration:
    php artisan make:migration create_users_table
  • Edit the generated file in database/migrations/.
  • Example migration:
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamps();
        });
    }
  • Run the migration:
    php artisan migrate

Creating and Using Models

Eloquent ORM simplifies database interactions.

  • Create a model:
    php artisan make:model User
  • Define relationships and attributes inside the model:
    class User extends Model
    {
        protected $fillable = ['name', 'email'];
    }
  • Fetch data:
    $users = User::all();

Relationships (One-to-Many, Many-to-Many)

One-to-Many Relationship

Example: A Post has many Comments.

  • Define in Post model:
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
  • Define inverse in Comment model:
    public function post()
    {
        return $this->belongsTo(Post::class);
    }

Many-to-Many Relationship

Example: A User has many Roles and vice versa.

  • Define in User model:
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
  • Define in Role model:
    public function users()
    {
        return $this->belongsToMany(User::class);
    }

4. Authentication & Middleware

Laravel Authentication using Laravel Breeze

Laravel Breeze provides a simple authentication setup.

  • Install Breeze:
    composer require laravel/breeze --dev
  • Install authentication scaffolding:
    php artisan breeze:install
  • Run migrations and serve the app:
    php artisan migrate
    php artisan serve

User Roles and Permissions

To manage roles, add a role column in the users table:

php artisan make:migration add_role_to_users_table

Modify migration:

$table->string('role')->default('user');

Restrict access based on roles:

if (auth()->user()->role !== 'admin') {
    abort(403);
}

Creating Custom Middleware for Access Control

Middleware restricts access based on conditions.

  • Create middleware:
    php artisan make:middleware AdminMiddleware
  • Define logic in app/Http/Middleware/AdminMiddleware.php:
    public function handle($request, Closure $next)
    {
        if (auth()->user() && auth()->user()->role !== 'admin') {
            return redirect('/home');
        }
        return $next($request);
    }
  • Register middleware in app/Http/Kernel.php:
    protected $routeMiddleware = [
        'admin' => \App\Http\Middleware\AdminMiddleware::class,
    ];
  • Apply middleware to routes:
    Route::get('/admin', function () {
        return view('admin.dashboard');
    })->middleware('admin');

6. CRUD Operations with Views

Setting up Routes and Controllers for CRUD

To implement CRUD operations, define routes and create controllers.

  • Create a controller:
    php artisan make:controller PostController --resource
  • Define routes in routes/web.php:
    Route::resource('posts', PostController::class);
  • Implement CRUD methods in PostController.php:
    public function index() {
        $posts = Post::paginate(10);
        return view('posts.index', compact('posts'));
    }

Creating Forms with Validation

  • Use Laravel’s form validation:
    public function store(Request $request) {
        $request->validate([
            'title' => 'required|min:3',
            'content' => 'required'
        ]);
        Post::create($request->all());
        return redirect()->route('posts.index')->with('success', 'Post created successfully');
    }
  • Display validation errors in Blade:
    @if ($errors->any())
        <div class="text-red-500">
            @foreach ($errors->all() as $error)
                <p>{{ $error }}</p>
            @endforeach
        </div>
    @endif

Displaying Data in Views with Pagination

  • Use Laravel’s pagination helper:
    <table>
        @foreach ($posts as $post)
            <tr>
                <td>{{ $post->title }}</td>
            </tr>
        @endforeach
    </table>
    {{ $posts->links() }}

Editing and Deleting Records

  • Edit and update a record:
    public function edit(Post $post) {
        return view('posts.edit', compact('post'));
    }
    
    public function update(Request $request, Post $post) {
        $post->update($request->all());
        return redirect()->route('posts.index')->with('success', 'Post updated');
    }
  • Delete a record:
    public function destroy(Post $post) {
        $post->delete();
        return redirect()->route('posts.index')->with('success', 'Post deleted');
    }

7. Reusable Components & UI Improvements

Creating Blade Components for Buttons, Forms, and Tables

  • Generate a component:
    php artisan make:component Button
  • Define props and merge attributes in resources/views/components/button.blade.php:
    @props(['type' => 'button', 'variant' => 'primary'])
    
    <button {{ $attributes->merge(['class' => "bg-$variant-500 text-white px-4 py-2 rounded"]) }} type="{{ $type }}">
        {{ $slot }}
    </button>
  • Use the component in views with custom props:
    <x-button type="submit" variant="blue" class="mt-4">Submit</x-button>

Using Tailwind CSS for Styling

  • Install Tailwind CSS:
    npm install -D tailwindcss
    npx tailwindcss init
  • Configure tailwind.config.js and include Tailwind in resources/css/app.css:
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
  • Apply styles in Blade:
    <div class="max-w-xl mx-auto p-6 bg-white shadow-md">
        <h1 class="text-xl font-bold">Welcome</h1>
    </div>

Implementing Flash Messages for User Feedback

  • Store flash messages in the session:
    return redirect()->route('posts.index')->with('success', 'Post created');
  • Display flash messages in Blade:
    @if (session('success'))
        <div class="bg-green-500 text-white p-2">
            {{ session('success') }}
        </div>
    @endif

8. Deployment and Optimization

Preparing Laravel for Production

Configure Environment Variables

  • Set APP_ENV=production and APP_DEBUG=false in the .env file.
  • Update database credentials and other production settings.

Optimize Performance

  • Run the following Artisan commands:
    php artisan config:cache
    php artisan route:cache
    php artisan view:cache
  • Use queues for background tasks:
    php artisan queue:work

File and Folder Permissions

  • Ensure proper permissions for storage and bootstrap/cache:
    chmod -R 775 storage bootstrap/cache

Deploying to a Web Server

  • Use Nginx or Apache.
  • Point the document root to the public folder.
  • Example Nginx configuration:
    server {
        listen 80;
        server_name example.com;
        root /var/www/html/laravel/public;
        index index.php index.html index.htm;
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php7.4-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }

Using Database Seeders and Factories for Test Data

Creating a Seeder

  • Generate a seeder:
    php artisan make:seeder UserSeeder
  • Modify the seeder in database/seeders/UserSeeder.php:
    public function run()
    {
        User::create([
            'name' => 'Admin',
            'email' => '[email protected]',
            'password' => bcrypt('password'),
        ]);
    }
  • Run the seeder:
    php artisan db:seed --class=UserSeeder

Creating a Factory

  • Generate a model factory:
    php artisan make:factory UserFactory --model=User
  • Define fake data in database/factories/UserFactory.php:
    public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'password' => bcrypt('password'),
        ];
    }
  • Use factories to generate test data:
    User::factory()->count(10)->create();
⚠️ **GitHub.com Fallback** ⚠️