”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 部分掌握 Laravel 从基础到高级 Web 开发

部分掌握 Laravel 从基础到高级 Web 开发

发布于2024-08-02
浏览:741

Part  Mastering Laravel From Fundamentals to Advanced Web Development

Mastering Laravel : From Fundamentals to Advanced Web Development

Eloquent Relationship: One To One

Creating a one-to-one relationship between an author and a profile in Laravel using Eloquent involves several steps, including creating migrations, models, and defining the relationship.

Create Migrations and model

php artisan make:model Author --migration

php artisan make:model Profil --migration

Define Migrations

Edit the migrations to define the structure of your tables.

authors migration may look something like this:

Schema::create('authors', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->timestamps();
});

profiles migration should include a foreign key referencing the authors table:

Schema::create('profiles', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('author_id');
    $table->string('bio');
    $table->timestamps();

    $table->foreign('author_id')->references('id')->on('authors')->onDelete('cascade');
});

Let's break down what each part of this statement does:

  1. $table->foreign('author_id'): This part of the statement is declaring that the author_id column in the profiles table is a foreign key. A foreign key is a field in one table, which is a primary key in another table. In this case, author_id in the profiles table will correspond to the id in the authors table.
  2. >references('id'): This specifies which column in the foreign table (authors) the author_id column is related to. Here, it's saying that author_id references the id column of the authors table. This creates a direct link between the two tables, where each author_id in the profiles table points to an id in the authors table.
  3. >on('authors'): This part specifies the name of the foreign table that the foreign key relates to. In this case, it's the authors table.
  4. >onDelete('cascade'): This is a referential action related to the foreign key. When a record in the parent table (authors) is deleted, the onDelete('cascade') action specifies that all records in the current table (profiles) that reference the deleted record should also be deleted. This helps in maintaining the integrity of your data. For example, if an author is deleted, their associated profile in the profiles table will also be automatically deleted, preventing orphaned records.

Define Eloquent Models

In your Eloquent models, define the one-to-one relationship.

In the Author model:

public function profile()
    {
        return $this->hasOne(Profil::class);
    }

In the Profil model:

public function author()
    {
        return $this->belongsTo(Author::class);
    }

Using the Relationship

With the relationships defined, you can now easily access the profile of an author and

do the opposite ;

To access the profile of an author:

$author = Author::find(1);
$profile = $author->profile;

To access the author of a profile:

$profile = Profile::find(1);
$author = $profile->author;

using tinker to associate an author with a profile

$author = new Author();

$author->save();

$profile = new Profile();

$author->profile()->save($profile);

//

$authors = Author::get();

// return list of authors with their profile

$authors = Author::with('profile')->get();

// return only one author
$author = Author::with('profile')->whereId(1)->first();

// list of profiles :

$profiles = Profile::get();

// list of profiles with authors :

$profiles = Profile::with('author')->get();

Eloquent Relationship: One To Many

Creating a one-to-Many relationship between an post and a comment in Laravel using Eloquent involves several steps, including creating migrations, models, and defining the relationship.

Create Migrations and Models

php artisan make:model Comment --migration

Comments Migration

The comments migration should include a foreign key referencing the posts table:

Schema::create('comments', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('post_id');
    $table->text('comment');
    $table->timestamps();

    $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
});

Define Eloquent Models

Now, define the relationships in the Eloquent models.

Post Model

In the Post model, define a relationship to access its comments:

public function comments()
    {
        return $this->hasMany(Comment::class);
    }

Comment Model

In the Comment model, define a relationship to access its parent post:

public function post()
    {
        return $this->belongsTo(Post::class);
    }

Associating Comments with a Post

Using Tinker or in your application logic, you can associate a comment with a post as follows:

$comment = new Comment();

$comment->comment= "first comment";

$post = new Post();

$post->comments()->save($comment);

// method 1
$comment = new Comment();

$comment->comment= "first comment";

$comment->post_id = x ;

$comment->save();

// method 2 : associate two comment to one post

$comment = new Comment();

$comment->comment= "first comment";

$comment1 = new Comment();

$comment1->comment= "second comment ";

$post = Post::find(3);

$post->comments()->saveMany([$comment,$comment1]);


Eloquent Relationship: Many To Many

create a many-to-many relationship in Laravel, let's use an example involving posts, comments, and introduce a new entity, tags, to demonstrate a many-to-many relationship, since a comment typically belongs to one post directly, making it a one-to-many relationship. Tags can be applied to posts and posts can have multiple tags, perfectly illustrating a many-to-many relationship.

Step 1: Create Migrations and Models for Tags

First, create a model for Tag with a migration, and also create a pivot table migration for the many-to-many relationship between posts and tags.

bashCopy code
php artisan make:model Tag --migration
php artisan make:migration create_post_tag_table --create=post_tag

Step 2: Migration for Tags

Edit the migration for tags to add the necessary fields.

phpCopy code
Schema::create('tags', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->timestamps();
});

Step 3: Migration for the Pivot Table

Define the pivot table post_tag to store the relationships between posts and tags.

phpCopy code
Schema::create('post_tag', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('post_id');
    $table->unsignedBigInteger('tag_id');
    $table->timestamps();

    $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
    $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});

Step 4: Define Eloquent Models Relationships

Post Model

In the Post model, define a relationship to access its tags.

public function tags()
{
    return $this->belongsToMany(Tag::class);
}

Tag Model

In the Tag model, define a relationship to access its posts.

public function posts()
{
    return $this->belongsToMany(Post::class);
}

Step 5: Associating Tags with Posts

You can associate tags with a post using Tinker or within your application logic. Here's an example of how to attach a tag to a post:

phpCopy code
$post = Post::find(1); 
$tag = Tag::find(1); 

// Attach the tag to the post
$post->tags()->attach($tag->id);

// Alternatively, if you have multiple tags to attach at once
$post->tags()->attach([$tagId1, $tagId2]);

To detach tags from a post:

// Detach a single tag from the post
$post->tags()->detach($tagId);

// Detach multiple tags from the post
$post->tags()->detach([$tagId1, $tagId2]);

// Detach all tags from the post
$post->tags()->detach();

This setup allows you to have a many-to-many relationship between posts and tags, where a post can have multiple tags and a tag can be associated with multiple posts.


lazy loading and Eager Loading

In the provided code snippets, we demonstrate two different approaches to retrieving a Comment model in Laravel, showcasing the difference between lazy and eager loading.

Lazy Loading Example:

$comment = comment::find(2);

In this line, we are retrieving the comment with ID 2 using the find method. This is an example of lazy loading, where the associated Post model is not loaded at the same time as the Comment. The Post data will only be loaded when explicitly accessed, for example, $comment->post, which would trigger an additional query to the database at that point.

Eager Loading Example:

$comment = comment::with('post')->find(2);

Here, we use the with('post') method to eagerly load the related Post model at the same time as the Comment. This means when the comment with ID 2 is fetched, the related Post is also retrieved in the same query operation. Eager loading is beneficial for performance when you know you will need the related model immediately, as it reduces the total number of queries made to the database.

In summary, the choice between lazy and eager loading in Laravel depends on the specific requirements of your application and when you need access to related models. Eager loading is generally used to optimize performance by reducing the number of database queries.

Example with our Project :

// mode lazy

public function index()
    {

        DB::connection()->enableQueryLog();

        $posts = Post::all();

        foreach ($posts as $post) {
            foreach ($post->comments as $comment) {
               dump($comment);
            }
        }

        return view('posts.index', [
            'posts' => $posts]);
    }

// mode eager

public function index()
    {

        DB::connection()->enableQueryLog();

        $posts = Post::with('comments')->get();

        foreach ($posts as $post) {
            foreach ($post->comments as $comment) {
               dump($comment);
            }
        }

        return view('posts.index', [
            'posts' => $posts]);
    }

Summary

  • Response Time: Eager loading can improve response times by reducing the number of database queries, especially in data-intensive scenarios.
  • Performance Optimization: Developers should choose between eager and lazy loading based on the specific use case, balancing the need for immediate data access against the potential cost of extra database queries.
  • Best Practice: In Laravel, it's generally a good practice to use eager loading for data that will definitely be used, especially when dealing with 'hasMany' relationships or when iterating over collections that access related models.

Model Factories

Model Factories in Laravel are a powerful feature for testing and seeding your database with dummy data. They allow you to easily generate fake data for your Eloquent models, which is extremely useful for automated testing and during development when you need to work with sample data. Here's a detailed description suitable for a course module:

Introduction to Model Factories

  • Purpose: Model Factories in Laravel are used to define a blueprint for how to generate fake data for a given model. This can be used to seed databases or for testing purposes.
  • Benefits: They promote DRY (Don't Repeat Yourself) principles by centralizing the logic for creating models with test data, making tests and seeders cleaner and more maintainable.

Creating a Model Factory

  • Command: Use the Artisan command php artisan make:factory [FactoryName] --model=[ModelName] to create a new factory.
  • Location: Factories are typically stored in the database/factories directory.
  • Structure: A factory file contains a definition method that returns an array of attribute values for the associated model.

Defining Factory States

  • Factories can have multiple "states", which are variations of the base factory. This is useful when you need different sets of data for the same model.
  • States are defined using the state method within the factory class.

Using Factories

  • Seeding: Factories can be used in database seeders to populate tables with fake data for development or testing.
  • Testing: In automated tests, factories can create models with predictable data, making it easier to test various scenarios.

Example

php artisan make:factory PostFactory

 */
class PostFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition(): array
    {
        $title = fake()->sentence();
        return [
            'title' => fake()->sentence(),
            'content' => fake()->text(2000), 
            'slug' => \Illuminate\Support\Str::slug($title), 
            'active' => fake()->boolean(), 
        ];
    }
}

Execute factory in the Tinker :

php artisan tinker 

Post::factory()->create();

php artisan make:migration add_userid_to_posts_table

The $table->foreignId('user_id')->constrained(); line in a Laravel migration represents the definition of a foreign key constraint within your database schema. Here's a breakdown of what each part means:

  • $table->foreignId('user_id'): This part creates a new column on the table named user_id that is intended to store unsigned big integers (BigInteger equivalent). This is commonly used for foreign keys that reference an id field in another table. The foreignId method is a shorthand in Laravel for creating such an integer column specifically designed to link to the id of another table, assuming that id is an unsigned big integer.
  • >constrained(): This method adds a foreign key constraint to the user_id column, linking it to the id column of another table. By default, without specifying a table name as a parameter to constrained(), Laravel assumes that the foreign key references the id column of a table whose name is the singular form of the column name before _id, following Laravel's naming conventions. In this case, user_id implies a reference to the id column of the users table.

This line effectively does two things:

  1. Creates a user_id column meant to hold references to the id of the users table.
  2. Establishes a foreign key constraint that enforces the integrity of this relationship, ensuring that each value in the user_id column corresponds to an existing id in the users table.

Database Seeding

Definition: Database seeding is the method of automatically populating a database with data. This data can be static, meant for configuration or initial state setup, or dynamically generated to simulate a database filled with user-generated content. Seeding is especially useful for developers and testers by providing a quick way to insert test data into a database without manually entering it.

Purpose:

  • To initialize a database with the data it needs to perform correctly upon startup.
  • To assist in automated testing by providing a consistent data state.
  • To aid in development by giving developers a set of data to work with.

How It Works:

  1. Preparation: Define the data that needs to be inserted into the database. This can include users, posts, settings, or any other entities relevant to the application.
  2. Implementation: Use the seeding capabilities provided by the development framework or database management tools. For example, Laravel provides a seeding system that allows the definition of seed classes, each responsible for seeding specific tables.
  3. Execution: Run the seeding process through the framework's CLI or a custom script. This process executes the seed classes, inserting the predefined data into the database.

Best Practices:

  • Idempotency: Make sure that running the seeding process multiple times does not create unwanted duplicates or errors. Achieve this by checking for existing data before seeding or by clearing relevant tables at the beginning of the seeding process.
  • Use Realistic Data: Especially for development and testing, using data that mimics real user input can help uncover issues and better understand how the application behaves.
  • Environment Awareness: Differentiate between the data needed for development, testing, and production. Sensitive data should not be used in development or testing databases.
      \App\Models\User::factory(10)->create();

        //\App\Models\User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => '[email protected]',
        // ]);

       \App\Models\Post::factory(10)->create();

Model relations inside seeder

When working with database seeders in a Laravel application, it's often necessary to create not just standalone records, but also to establish relationships between them. This is crucial for reflecting the real-world connections between different entities in your application, such as users having posts, or orders being linked to customers. Here's how you can handle model relationships inside a database seeder in Laravel.

Creating Related Models

When seeding data, you typically start by creating instances of your root model. For related models, you can utilize Laravel's relationship methods to create and associate them seamlessly.

One-to-Many Relationship Example

Suppose you have two models, User and Post, with a one-to-many relationship (a user can have many posts). Here's how you could seed this relationship:

//Model relations inside seeder

        $users = \App\Models\User::factory(10)->create();

        \App\Models\Post::factory(10)->make()->each(function ($post) use ($users) {
            $post->user_id = $users->random()->id;
            $post->save();
        });

Individual seeder classes

In Laravel, using individual seeder classes for each model can help organize your database seeds, making them more maintainable and readable, especially in larger applications. This approach allows you to separate the seeding logic for different parts of your application into distinct classes. Here's a guide on how to use individual seeder classes effectively.

Step 1: Creating Seeder Classes

To create a new seeder class, you can use the Artisan command provided by Laravel. For example, to create a seeder for the User model, you would run:

php artisan make:seeder UsersTableSeeder

php artisan make:seeder PostsTableSeeder

User seeder

create();
    }
}

Post Seeder

make()->each(function ($post) use ($users) {
            $post->user_id = $users->random()->id;
            $post->save();
        });
    }
}

Linking Seeder Classes in DatabaseSeeder

The DatabaseSeeder class is the root seeder class that's called when you run the database seed command. To use your individual seeder classes, you need to call them from the run method of the DatabaseSeeder class:

$this->call([
            UsersTableSeeder::class,
            PostsTableSeeder::class,
        ]);

Making seeder interactive

Making a Laravel seeder interactive allows you to dynamically specify aspects of the seeding process at runtime, such as how many records to create. This approach can be particularly useful during development or when running seeders in different environments, providing flexibility without the need to modify the seeder code for each run. Here's how you can make a Laravel seeder interactive:

Step 1: Use the Command Line Interface (CLI)

Laravel seeders can interact with the user through the CLI by using the ask method available in the seeder class. This method is part of the Illuminate\Console\Command class, which seeders have access to via the command property.

Example: Interactive User Seeder

Let's create an interactive seeder that asks how many users to create.

command->ask('How many users do you want to create?', 10);

        // Create the specified number of users using the User factory
        \App\Models\User::factory((int)$count)->create();

        $this->command->info("Successfully created {$count} users.");

       //  \App\Models\User::factory(10)->create();
    }
}

refresh database before creating new seeders

if($this->command->confirm('Do you want to refresh the database?', true)) {
            $this->command->call('migrate:refresh');
            $this->command->info('Database was refreshed.');
        }

$this->call([
            UsersTableSeeder::class,
            PostsTableSeeder::class,
        ]);

check if users exist

count() == 0) {
            $this->command->info('Please create some users first.');
            return;
        }

        \App\Models\Post::factory(10)->make()->each(function ($post) use ($users) {
            $post->user_id = $users->random()->id;
            $post->save();
        });
    }
}
php artisan db:seed --class=PostsTableSeeder

Unit Testing

Creating a comprehensive tutorial on testing user and post functionality in a Laravel application involves several steps, including setting up the environment, writing tests for both models and their relationships, and ensuring that all functionalities work as expected. This tutorial will cover the basics of setting up Laravel for testing, creating unit tests for models, and feature tests for user interactions with posts.

Step 1: Setting Up the Testing Environment

First, ensure your Laravel application is set up for testing. Laravel uses PHPUnit for testing, configured out of the box. Check that the phpunit.xml file exists in your project root; this file configures your testing environment. You might want to configure your database for testing by setting the DB_CONNECTION environment variable in phpunit.xml to use a different database, like SQLite, for faster tests.


php artisan test
php artisan make:test HomeTest

get('/home');

        $response->assertStatus(200);
    }

    public function test_home_page_contains_text(): void
    {
        $response = $this->get('/home');

        $response->assertSeeText('Home pge');
    }
}

Step 2: Writing Unit Tests for Models

Before writing feature tests, it's a good practice to start with unit tests for your models to ensure your basic relationships and business logic are correct.

Testing User Model

Create a test file for the User model:

php artisan make:test UserTest --unit

Write tests in tests/Unit/UserTest.php to verify the User-Post relationship:

assertTrue(true);
    }

    /** @test */
    public function user_can_have_posts()
    {
        $user = User::factory()->create();
        $post = Post::factory()->create(['user_id' => $user->id]);

        // Use the load method to refresh the posts relationship
        $user->load('posts');

        $this->assertTrue($user->posts->contains($post));
    }
}

This test checks that a user can have associated posts.

In the context of Laravel's testing utilities, the assertDatabaseHas and assertDatabaseMissing methods are used to inspect the application's database and assert whether it contains or lacks certain data, respectively. These assertions are particularly useful for feature tests where you're testing the application's behavior as it interacts with the database. Here's a closer look at both methods:

assertDatabaseHas

The assertDatabaseHas method asserts that data exists in the database. This method is helpful when you want to ensure that a database operation, such as creating or updating a record, was successful.

Example:

Suppose you have a test that creates a post. To verify that the post was successfully created and exists in the posts table, you might use assertDatabaseHas like this:

$this->assertDatabaseHas('posts', [
    'title' => 'Example Post Title',
    'content' => 'The content of the example post.',
]);

assertDatabaseMissing

Conversely, the assertDatabaseMissing method asserts that specific data does not exist in the database. This method is useful for testing deletions or ensuring that a record was not created due to validation or authorization failures.

Example:

If you have a test that deletes a post, you can use assertDatabaseMissing to ensure that the post no longer exists in the posts table:

$this->assertDatabaseMissing('posts', [
    'id' => $postId,
]);

Step 3: Writing Feature Tests for User Interactions with Posts

Feature tests simulate real user interactions with your application. Here, we'll write a test to ensure users can create and view posts.

Testing Post Creation and Viewing

Generate a test file for post interactions:

php artisan make:test PostTest

Write tests in tests/Feature/PostTest.php to simulate creating and viewing posts:

actingAs(User::factory()->create());

        $postData = [
            'title' => 'Sample Post Title',
            'content' => 'This is the content of the post.',
        ];

        $this->post('/posts', $postData)->assertStatus(302); // Assuming redirection after creation

        $this->assertDatabaseHas('posts', $postData);
    }

    /** @test */
    public function a_user_can_view_a_post()
    {
        $post = Post::factory()->create();

        $this->get("/posts/{$post->id}")
             ->assertStatus(200)
             ->assertSee($post->title)
             ->assertSee($post->content);
    }
}
// adjust our controller store post method : 
// method 1 
        $post = new Post();
        $post->title = $request->input('title');
        $post->content = $request->input('content');
        $post->slug= Str::slug($post->title, '-');
        $post->active = false;
        $post->user_id = auth()->id(); // or $request->user()->id;  
        $post->save();

Running the Tests

To run your tests, use the PHPUnit command:

php artisan test

Testing update and Delete

public function a_user_can_update_a_post()
{
    $user = User::factory()->create();
    $this->actingAs($user);

    $post = Post::factory()->create(['user_id' => $user->id]);

    $updatedData = [
        'title' => 'Updated Post Title',
        'content' => 'Updated content of the post.',
    ];

    $response = $this->put("/posts/{$post->id}", $updatedData);

    $response->assertStatus(302); // Assuming a redirect occurs after update

    $this->assertDatabaseHas('posts', [
        'id' => $post->id,
        'title' => 'Updated Post Title',
        'content' => 'Updated content of the post.',
    ]);
}

// Delete

public function a_user_can_view_a_post()
{
    $user = User::factory()->create();
    $this->actingAs($user);

    $post = Post::factory()->create(['user_id' => $user->id]);

    $response = $this->get("/posts/{$post->id}");

    $response->assertStatus(200);
    $response->assertSee($post->title);
    $response->assertSee($post->content);
}

Telescope

Laravel Telescope is an elegant debug assistant for Laravel applications. It provides insight into the requests coming into your application, exceptions, database queries, queued jobs, mail, notifications, cache operations, scheduled tasks, variable dumps, and more. Telescope is designed to make the development process easier by providing a convenient and powerful user interface to monitor your application's operations in real time.

Key Features of Laravel Telescope:

  • Requests: Tracks incoming requests, including response times, payload, and status codes, helping you identify performance bottlenecks or problematic requests.
  • Exceptions: Logs exceptions thrown within your application, providing stack traces and context to help with debugging.
  • Database Queries: Shows all database queries executed during a request, including execution time and the ability to detect duplicate queries that could affect performance.
  • Mail: Records all outgoing emails sent by the application, allowing you to inspect mail content, headers, and recipients.
  • Notifications: Monitors notifications dispatched by your application, useful for debugging notification delivery issues.
  • Jobs: Provides details on queued jobs, including their payload, status (pending, completed, failed), and execution time.
  • Cache: Displays cache operations, making it easier to understand how your cache is being utilized and identify unnecessary cache hits or misses.
  • Scheduled Tasks: Keeps track of scheduled tasks, showing when tasks are executed and how long they take, helping ensure your task scheduling is working as expected.
  • Dumps: Telescope includes a dump watcher, which captures data dumped using the dump() method, making it available in the Telescope interface instead of your application's output.
  • Redis Commands: If your application uses Redis, Telescope can track Redis commands to give you insight into how Redis is being used.

Installation and Setup:

To install Telescope, you typically run the following Composer command in your Laravel project:

composer require laravel/telescope

After installation, publish its assets and run the migrations:

php artisan telescope:install
php artisan migrate

Accessing Telescope:

Once installed, Telescope can be accessed via your web browser at the /telescope path of your application (e.g., http://127.0.0.1:8000/telescope). Access to Telescope can and should be restricted in production environments to prevent unauthorized access to sensitive application data.

Use Cases:

  • Development: During development, Telescope can be used to debug and optimize your application by providing real-time insights into its operations.
  • Staging: In a staging environment, Telescope helps in performing final checks before going live, ensuring that no unexpected issues or performance bottlenecks have been introduced.
  • Production: While it's less common to have Telescope enabled in production due to performance considerations and the sensitivity of the data it exposes, it can be configured to only keep a limited set of data or to be accessible only by certain IP addresses or users.

Conclusion:

Laravel Telescope is an invaluable tool for Laravel developers, offering a rich set of features to improve application development, debugging, and performance optimization. Its user-friendly interface and comprehensive monitoring capabilities make it a must-have for serious Laravel projects.


Authentication

Step 1: Installing Laravel UI

First, you install the Laravel UI package using Composer:

composer require laravel/ui

This command adds the Laravel UI package to your project, allowing you to generate the basic scaffolding for authentication, as well as frontend presets for Vue.js, Bootstrap, or React.

Step 2: Generating the Auth Scaffolding

Once Laravel UI is installed, you can generate the authentication scaffolding. If you're interested in using Vue.js along with the authentication system, you can do so with the following command:

php artisan ui vue --auth

This command does two main things:

  1. Vue.js Scaffolding: It sets up Vue.js in your Laravel application by generating example components and setting up webpack.mix.js for compiling your assets.
  2. Authentication Scaffolding: It generates the necessary views, routes, and controllers for a basic authentication system. This includes login, registration, password reset, and email verification views, along with the routes and controllers needed to handle these functionalities.

Step 3: Compiling the Assets

After running the ui vue --auth command, you'll need to compile your assets (JavaScript and CSS) to reflect the changes in your application. You can do this with Laravel Mix by running:

npm install && npm run dev
php artisan migrate

now let adjust our redirect page after login and register in RouteServiceProvider :

public const HOME = '/home'; 

//to 

public const HOME = '/posts';

Retrieving the Currently Authenticated User

Laravel provides several methods through its Auth facade to access the currently authenticated user. Understanding these methods helps in managing user-specific data and enforcing access controls. Here are some examples:

  1. Get the ID of the Authenticated User:

    $userId = Auth::id();
    
    

    This method returns the identifier of the authenticated user without loading the user model. It's useful when you only need the user's ID for database queries or logging.

  2. Retrieve the Authenticated User Instance:

    $user = Auth::user();
    
    

    This method loads and returns the entire user model instance. It's helpful when you need more than just the user's ID, such as the user's name, email, or other attributes stored in the user table.

  3. Accessing Specific Attributes of the Authenticated User:

    $userEmail = Auth::user()->email;
    
    

    After retrieving the user model instance, you can access any of its attributes. This example demonstrates how to get the email of the authenticated user.

  4. Check If a User is Authenticated:

    $isAuthenticated = Auth::check();
    
    

    This method checks if the current visitor is authenticated. It returns true if the user is logged in and false otherwise. This is particularly useful for conditionally showing content or redirecting users.

Protecting Routes (Requiring Authentication)

Protecting routes is crucial to prevent unauthorized access to certain parts of your application. Laravel makes it straightforward to require authentication for specific routes using middleware.

Example of Protecting Routes:

use App\Http\Controllers\HomeController;
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;

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

// Authentication Routes
Auth::routes();

// Protected routes
Route::middleware(['auth'])->group(function () {
    Route::get('/home', [HomeController::class, 'index'])->name('home');
    Route::get('/about', [HomeController::class, 'about'])->name('about');
    Route::resource('posts', PostController::class);
});

Controller-based Middleware Protection:

use App\Http\Controllers\HomeController;
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;

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

// Authentication Routes
Auth::routes();

// Protected routes
Route::middleware(['auth'])->group(function () {
    Route::get('/home', [HomeController::class, 'index'])->name('home');
    Route::get('/about', [HomeController::class, 'about'])->name('about');

});

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

the constructor method of the PostController class is using $this->middleware('auth')->only(['create', 'edit', 'update', 'destroy']); to specify that only authenticated users are allowed to access the create, edit, update, and destroy actions. Here's a breakdown of what this does:

  • $this->middleware('auth'): This applies the auth middleware, ensuring that only authenticated users can proceed.
  • >only(['create', 'edit', 'update', 'destroy']): This limits the middleware application only to the specified methods. Other methods in this controller, such as index or show, would not require authentication, making them accessible to unauthenticated users.
public function __construct()
    {
        $this->middleware('auth')->only(['create', 'edit', 'update', 'destroy']);
    }

If you want to apply middleware to all controller actions except for a selected few, you can use the except method instead of only. This is useful when most of your controller's actions require middleware, but a few public actions should remain accessible without it.

Here's how you can modify your constructor to use except:

public function __construct()
{
    $this->middleware('auth')->except(['index', 'show']);
}


Soft Deletes & Hard Deletes

To implement Soft Deletes and Hard Deletes in Laravel models like User and Post, you first need to understand what each type of deletion entails and then see how to apply them to these models.

Soft Deletes

Soft deleting is a way to "delete" a model without actually removing it from the database. Instead, a deleted_at timestamp is set on the model. This approach lets you recover the "deleted" models later if needed.

How to Implement Soft Deletes:

Create a New Migration

First, you need to create a new migration file for the table you wish to add soft deletes to. If you're modifying an existing table, you'll still create a migration but structure it to alter the table rather than create a new one. Use the Artisan CLI to create this migration:

php artisan make:migration add_soft_deletes_to_posts_table --table=posts

Modify the Migration File

Open the newly created migration file in your editor. It will be named with a timestamp and the description you provided, something like 2024_01_01_000000_add_soft_deletes_to_posts_table.php.

Modify the up method to add a deleted_at column to the table. This column is used by Laravel to mark when a record was "deleted":

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddSoftDeletesToPostsTable extends Migration
{
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->softDeletes(); // Adds the deleted_at column
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropSoftDeletes(); // Removes the deleted_at column
        });
    }
}

Run the Migration

Apply the migration to your database to alter the posts table by adding the deleted_at column:

php artisan migrate

Update Your Model

To enable soft deletes in your Eloquent model, you must use the Illuminate\Database\Eloquent\SoftDeletes trait in the model that corresponds to the table you've just modified. Open or create the model file in app/Models/Post.php and update it as follows:

belongsTo(User::class);
    }

        public function comments()
        {
        return $this->HasMany(Comment::class);
        }


}
$post = Post::find($postId);
$post->delete();

To retrieve soft-deleted models, you can use the withTrashed() method on your model query:

$posts = Post::withTrashed()->get();

This approach ensures that when a Post model is deleted, all of its associated Comment models are also deleted, mimicking the behavior of a database-level ON DELETE CASCADE constraint.

// example without on cascade
        public static function boot(){
        parent::boot();

        static::deleting(function(Post $post){
        $post->comments()->delete();
        });

        }

Hard Deletes

Hard deleting is the conventional way of deleting records from the database. Once a model is hard deleted, it's permanently removed from the database.

Implementing Hard Deletes:

Hard deletes don't require any special setup in Laravel; they are the default behavior when you call the delete method on a model instance without using the SoftDeletes trait.

Example of Force Delete (Hard Delete):

$post = Post::withTrashed()->find($postId);
$post->forceDelete();

implements new logic to our Posts Controller :

// Existing soft delete method
public function destroy(Request $request, string $id)
{
    $post = Post::findOrFail($id);
    $post->delete(); // Soft delete

    $request->session()->flash('status', 'Post was deleted!');
    return redirect()->route('posts.index');
}

// Add this method for hard (force) delete
public function forceDestroy(Request $request, string $id)
{
    $post = Post::withTrashed()->findOrFail($id);
    $post->forceDelete(); // Permanently deletes the post

    $request->session()->flash('status', 'Post was permanently deleted!');
    return redirect()->route('posts.index');
}

index.blade.php

@extends('layouts.app')

@section('content')
    

list of Post

    @if(session()->has('status'))

    {{session()->get('status')}}

    @endif @forelse($posts as $post)
  • $post->id])}}">{{$post->title}}

    $post->id])}}">Edit
    @csrf @method('DELETE')
    @csrf @method('DELETE')

    {{$post->content}}

    {{$post->created_at}}
  • @empty

    No blog post yet!

    @endforelse
@endsection

ADD NEW ROUTE :

Route::delete('/posts/{id}/force', [PostController::class, 'forceDestroy'])->name('posts.forceDestroy');
版本声明 本文转载于:https://dev.to/chabbasaad/part-2-mastering-laravel-from-fundamentals-to-advanced-web-development-3ia2?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • JavaScript ESelease 笔记:释放现代 JavaScript 的力量
    JavaScript ESelease 笔记:释放现代 JavaScript 的力量
    JavaScript ES6,正式名称为 ECMAScript 2015,引入了重大增强功能和新功能,改变了开发人员编写 JavaScript 的方式。以下是定义 ES6 的前 20 个功能,它们使 JavaScript 编程变得更加高效和愉快。 JavaScript ES6 的 2...
    编程 发布于2024-11-06
  • 了解 Javascript 中的 POST 请求
    了解 Javascript 中的 POST 请求
    function newPlayer(newForm) { fetch("http://localhost:3000/Players", { method: "POST", headers: { 'Content-Type': 'application...
    编程 发布于2024-11-06
  • 如何使用 Savitzky-Golay 滤波平滑噪声曲线?
    如何使用 Savitzky-Golay 滤波平滑噪声曲线?
    噪声数据的平滑曲线:探索 Savitzky-Golay 过滤在分析数据集的过程中,平滑噪声曲线的挑战出现在提高清晰度并揭示潜在模式。对于此任务,一种特别有效的方法是 Savitzky-Golay 滤波器。Savitzky-Golay 滤波器在数据可以通过多项式函数进行局部近似的假设下运行。它利用最小...
    编程 发布于2024-11-06
  • 重载可变参数方法
    重载可变参数方法
    重载可变参数方法 我们可以重载一个采用可变长度参数的方法。 该程序演示了两种重载可变参数方法的方法: 1 各种可变参数类型:可以重载具有不同可变参数类型的方法,例如 vaTest(int...) 和 vaTest(boolean...)。 varargs 参数的类型决定了将调用哪个方法。 2 添加公...
    编程 发布于2024-11-06
  • 如何在经典类组件中利用 React Hooks?
    如何在经典类组件中利用 React Hooks?
    将 React Hooks 与经典类组件集成虽然 React hooks 提供了基于类的组件设计的替代方案,但可以通过将它们合并到现有类中来逐步采用它们成分。这可以使用高阶组件 (HOC) 来实现。考虑以下类组件:class MyDiv extends React.component { co...
    编程 发布于2024-11-06
  • 如何使用 Vite 和 React 构建更快的单页应用程序 (SPA)
    如何使用 Vite 和 React 构建更快的单页应用程序 (SPA)
    在现代 Web 开发领域,单页应用程序 (SPA) 已成为创建动态、快速加载网站的流行选择。 React 是用于构建用户界面的最广泛使用的 JavaScript 库之一,使 SPA 开发变得简单。然而,如果你想进一步提高你的开发速度和应用程序的整体性能,Vite 是一个可以发挥重大作用的工具。 在本...
    编程 发布于2024-11-06
  • JavaScript 中字符串连接的分步指南
    JavaScript 中字符串连接的分步指南
    JavaScript 中的字符串连接 是将两个或多个字符串连接起来形成单个字符串的过程。本指南探讨了实现此目的的不同方法,包括使用运算符、= 运算符、concat() 方法和模板文字。 每种方法都简单有效,允许开发人员为各种用例(例如用户消息或 URL)构建动态字符串。 模板文字尤其为字符串连...
    编程 发布于2024-11-06
  • Web UX:向用户显示有意义的错误
    Web UX:向用户显示有意义的错误
    拥有一个用户驱动且用户友好的网站有时可能会很棘手,因为它会让整个开发团队将更多时间花在不会为功能和核心业务增加价值的事情上。然而,它可以在短期内帮助用户并在长期内增加价值。对截止日期严格要求的项目经理可能会低估长期的附加值。我不确定苹果网站团队是否属实,但他们缺少一些出色的用户体验。 最近,我尝试从...
    编程 发布于2024-11-06
  • 小型机械手
    小型机械手
    小型机械臂新重大发布 代码已被完全重构并编码为属性操作的新支持 这是一个操作示例: $classFile = \Small\ClassManipulator\ClassManipulator::fromProject(__DIR__ . '/../..') ->getC...
    编程 发布于2024-11-06
  • 机器学习项目中有效的模型版本管理
    机器学习项目中有效的模型版本管理
    在机器学习 (ML) 项目中,最关键的组件之一是版本管理。与传统软件开发不同,管理机器学习项目不仅涉及源代码,还涉及随着时间的推移而演变的数据和模型。这就需要一个强大的系统来确保所有这些组件的同步和可追溯性,以管理实验、选择最佳模型并最终将其部署到生产中。在这篇博文中,我们将探索有效管理 ML 模型...
    编程 发布于2024-11-06
  • 如何在 PHP 中保留键的同时按列值对关联数组进行分组?
    如何在 PHP 中保留键的同时按列值对关联数组进行分组?
    在保留键的同时按列值对关联数组进行分组考虑一个关联数组的数组,每个数组代表一个具有“id”等属性的实体和“名字”。面临的挑战是根据特定列“id”对这些数组进行分组,同时保留原始键。为了实现这一点,我们可以使用 PHP 的 foreach 循环来迭代数组。对于每个内部数组,我们提取“id”值并将其用作...
    编程 发布于2024-11-06
  • 如何在 Gradle 中排除特定的传递依赖?
    如何在 Gradle 中排除特定的传递依赖?
    用 Gradle 排除传递依赖在 Gradle 中,使用应用程序插件生成 jar 文件时,可能会遇到传递依赖,您可能想要排除。为此,可以使用排除方法。排除的默认行为最初,尝试排除 org.slf4j:slf4j- 的所有实例log4j12 使用以下代码:configurations { runt...
    编程 发布于2024-11-06
  • 极简生活的艺术
    极简生活的艺术
    什么是极简生活? 极简生活是一种有意减少拥有的财产数量和生活中杂乱的生活方式。这不仅是为了整理您的空间,也是为了简化您的生活,专注于真正重要的事情,并减少干扰。 为什么采用极简主义? 头脑清晰:拥有的东西越少,需要担心的事情就越少,头脑就越清晰。 财务自由:通过减少...
    编程 发布于2024-11-06
  • Java 混淆之谜
    Java 混淆之谜
    Come play with our Java Obfuscator & try to deobfuscate this output. The price is the free activation code! Obfuscated Java code Your goal...
    编程 发布于2024-11-06
  • 如何在没有图像的 Outlook 电子邮件中创建圆角?
    如何在没有图像的 Outlook 电子邮件中创建圆角?
    在没有图像的 Outlook 中设置圆角样式使用 CSS 在电子邮件客户端中创建圆角可以非常简单。但是,使用 CSS border-radius 属性的传统方法在 Microsoft Outlook 中不起作用。在设计具有圆角元素的电子邮件时,此限制提出了挑战。不用担心,有一种解决方案可以让您在 O...
    编程 发布于2024-11-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3