Laravel 7 新特性-路由的趟坑之路(自定义键名以及作用域)

2020-03-25 19:30:02 浏览数 (1)

Laravel 7 开始新增了一些新特性,今天我们来讲解下 路由绑定的新用法,自定义键名(slug)以及作用域(范围限定)

首先我们 安装最新版本的 Laravel ,并且创建两张数据表。

安装 Laravel 7

代码语言:javascript复制
composer create-project --prefer-dist laravel/laravel blog

生成用户认证脚手架

代码语言:javascript复制
composer require laravel/ui

npm install && npm run dev

我们使用内置服务,来启动一个 web server

代码语言:javascript复制
php artisan serve

生成用户填充数据

首先修改 .env 文件。修改数据库信息

代码语言:javascript复制
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=root
DB_PASSWORD=root

注意:我这里使用 laradock ,所以 DB_HOSTmysql

新建 Post 文章数据表

代码语言:javascript复制
php artisan make:model Post -mfcs

创建 Post 表字段,修改 databasemigrations日期_create_posts_table.php 文件

代码语言:javascript复制
<?php

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->bigInteger('user_id')->unsigned();
            $table->string('title');
            $table->text('body');
            $table->string('slug');
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

生成 数据表

代码语言:javascript复制
php artisan migrate

添加 Post 数据工厂,修改 databasefactoriesPostFactory.php 文件

代码语言:javascript复制
<?php

/** @var IlluminateDatabaseEloquentFactory $factory */

use AppPost;
use FakerGenerator as Faker;

$factory->define(Post::class, function (Faker $faker) {
    return [
        'user_id' => AppUser::all()->random(1)->first()->id,
        'title' => $faker->title,
        'body' => $faker->text,
        'slug' => $faker->slug,
    ];
});

用户数据填充

代码语言:javascript复制
php artisan make:seed UsersTableSeeder
代码语言:javascript复制
<?php

use IlluminateDatabaseSeeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(AppUser::class,5)->create();
    }
}

Post 数据填充

代码语言:javascript复制
<?php

use IlluminateDatabaseSeeder;

class PostSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(AppPost::class,50)->create();
    }
}

注册数据填充 database/seeds/DatabaseSeeder.php

代码语言:javascript复制
<?php

use IlluminateDatabaseSeeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
         $this->call(UsersTableSeeder::class);
         $this->call(PostSeeder::class);
    }
}

运行迁移文件,进行数据填充

代码语言:javascript复制
php artisan db:seed

ok,以上准备工作做完,(其实你大可不必这样,你可以任意创建 User、Post 数据表)我们正式开始今天的话题。

自定义键

首先我们来说一下自定义键是个什么东西,你可能知道,我们如果要查找一个数据,比如,我们要查询 Posts 文章表里的第一条数据。我们的以前的 URL 可能是如下这样:

代码语言:javascript复制
http://laravel7.test/posts/posts/1

我们是通过主键 ID 来进行查找的。这种方法 看起来没什么问题,但是我们网站有多少数据用户是可以轻而易举地猜到。

当然我们在以前的版本可以更改这个,我们需要在 模型中重写一个方法 getRouteKeyName

接下来我们看下 Laravel 7 以前是怎么实现的

首先。定义一个路由

代码语言:javascript复制
Route::get('posts/{post}', function (AppPost $post) {
    dd($post);
});

接下来,我们重写 Post 模型文件 getRouteKeyName 方法。

代码语言:javascript复制
public function getRouteKeyName()
{
    return 'slug';
}

接下来我们就可以使用 slug 来进行查询了 比如下面的 URL

代码语言:javascript复制
http://laravel7.test/posts/amet-laudantium-reprehenderit-ullam-repudiandae

Laravel 7 的版本,实现以上自定义键,就更加方便了 只需要在 路由上添加一个动态参数即可。

代码语言:javascript复制
Route::get('posts/{post:slug}', function (AppPost $post) {
    dd($post);
});

作用域(访问限制)

怎么理解呢?举一个应用场景,我们要限定查找用户,然后在当前用户下查找他发表的文章某一篇文章。

我们代码演示一下

代码语言:javascript复制
Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

首先 我们看下 数据库文章表的数据

假如我们查找文章 id 为 1,同时 他的 user_id 是 2, 那么访问的路由就是

代码语言:javascript复制
http://laravel7.test/api/users/2/posts/1

那么我们在查找 id 为 2 的数据,可以看到 他的 user_id 并不是 2 了,理论上我们不应该查到才是。

代码语言:javascript复制
http://laravel7.test/api/users/2/posts/2

然而实际情况确 并非如此。数据也是返回来了。

文档上就是这样呀?就是改变路由文件而已,照着做了,发现并不可以。

其实如果我们要实现如上的模式,我们还得需要设置模型的绑定关系

Post 模型

代码语言:javascript复制
<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

User 模型

代码语言:javascript复制
public function posts()
{
    return $this->hasMany(Post::class);
}

OK,再试着访问下,纳尼,为什么还是可以访问到???

最终看了半天文档 我发现他给的路由后面有一个 动态参数 slug,加上试试。

代码语言:javascript复制
Route::get('api/users/{user}/posts/{post:slug}', function (AppUser $user, AppPost $post) {
    return $post;
});

那么 路由就得换成如下的方式:

代码语言:javascript复制
http://laravel7.test/api/users/2/posts/et-saepe-enim-minus-et

这下终于可以了,终于实现我们想要的效果了。但是 难道非得是 slug 吗?我换成 id 不行吗?

代码语言:javascript复制
Route::get('api/users/{user}/posts/{post:id}', function (AppUser $user, AppPost $post) {
    return $post;
});

这样也是可以的。

好了,以上就是 Laravel 7 路由的新特性,外加我趟过的坑,希望对你有帮助。

版权许可

本作品采用 知识共享署名 4.0 国际许可协议 进行许可。 转载无需与我联系,但须注明出处,注明文章来源 Laravel 7 新特性-路由的趟坑之路(自定义键名以及作用域)

联系我

0 人点赞