基于 Laravel 8 模型工厂快速生成后端接口测试数据


继续后续 Vue 教程之前,我们先将 Laravel 后端文章数据表创建出来,并填充测试数据,以方便后续教程更快捷地提供后端测试接口。

创建模型类和数据表

在 Laravel 项目中,创建基于 MySQL 数据库的 MVC 模板代码非常简单,前面视图文件我们已经提供了,这里只需要创建模型类、控制器和对应数据表迁移文件即可,我们可以通过下面这条 Artisan 命令一次性创建:

php artisan make:model -mc Post --resource

-w803

该命令会在 app/Models 目录下生成 Post 模型类,在 database/migrations 目录下生成 posts 表对应的数据库迁移文件,以及在 app/Http/Controllers 目录下生成一个资源控制器 PostController

我们先来编辑数据表迁移文件,打开 component-practice/database/migrations/2020_10_24_140856_create_posts_table.php,在 up 方法中编写数据表字段如下:

<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->bigInteger('user_id')->unsigned()->index();
            $table->tinyInteger('status')->unsigned()->default(0);
            $table->timestamps();
        });
    }

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

然后运行 php artisan migrate 在数据库创建这张 posts 数据表。

-w774

编写模型工厂

创建完数据表后,就可以往里面填充测试数据了,在 Laravel 项目中,可以基于模型工厂快速填充测试数据,Laravel 8 完全重构了之前的模型工厂实现,下面学院君来简单演示下新版基于类的模型工厂的使用。

首先通过如下 Artisan 命令创建模型工厂类:

php artisan make:factory PostFactory

然后在打开新建的 database/factories/PostFactory.php 文件,在 definition 方法中定义针对 Post 模型工厂的测试数据生成策略(基于 Faker 对象伪造):

<?php

namespace Database\Factories;

use App\Models\Post;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'title' => $this->faker->sentence,
            'content' => $this->faker->text,
            'user_id' => User::factory(),
            'status' => rand(0, 1)
        ];
    }
}

这里由于 user_id 字段是与 User 模型类关联的外键,所以通过 User::factory() 映射到 User 模型工厂。当我们通过 Post 模型工厂创建文章实例的时候,也会顺便新建一个 User 对象实例并与这个 Post 对象实例关联。

定义 Post 与 User 的关联关系

接下来,打开 app/Models/Post.php,定义 Post 模型类如下:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];

    public function author()
    {
        return $this->belongsTo(User::class, 'user_id');
    }
}

我们通过 author 关联方法定义了 UserPost一对多关联,相应的,在 User 模型类中,也定义了一个与之相对的 post 关联方法:

public function posts()
{
    return $this->hasMany(Post::class, 'user_id');
}

运行模型工厂

我们可以在填充器测试类中运行模型工厂生成测试数据,也可以通过 Tinker 运行,下面我们在 Tinker 中通过 Post 模型工厂生成 30 条文章记录:

-w684

执行上述命令成功后,可以在数据库看到对应的文章记录:

-w1318

同时也会创建 30 条用户记录。至此,我们的文章测试数据就准备好了。

编写资源控制器和路由

完成测试数据的准备工作后,我们打开 app/Http/Controllers/PostController.php,编写资源控制器方法作为路由处理器,这里我们仅实现 indexallcreatestore 方法,:

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class PostController extends Controller
{
    public function __construct()
    {
        // 文章浏览无需认证
        $this->middleware('auth')->except('index', 'all', 'show');
    }

    /**
     * 文章列表视图
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('posts');
    }

    /**
     * 客户端通过 Axios 异步获取所有文章数据
     *
     * @return \Illuminate\Http\Response
     */
    public function all()
    {
        return Post::all();
    }

    /**
     * 渲染文章发布表单视图
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('form');
    }

    /**
     * 新发布文章保存操作
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required',
            'author' => 'required',
            'content' => 'required'
        ]);

        $post = new Post();
        $post->fill($data);
        $post->status = 1;
        $post->user_id = Auth::user()->id;
        
        return $post->save();
    }
    
    ...

最后,我们打开路由文件 routes/web.php,将之前的文章路由处理改为通过 PostController 这个资源控制器提供的方法来处理:

use App\Http\Controllers\PostController;

Route::get('posts/all', [PostController::class, 'all']);
Route::resource('posts', PostController::class);

非常简单,不多做介绍了。至此,我们就完成了所有后端接口路由、测试数据的准备工作。

在前端验证返回测试数据的接口

由于获取所有文章的接口路由改了,所以我们需要修改 resources/js/components/PostList.vue 中的接口路径为 /posts/all

mounted() {
    axios.get('/posts/all').then(resp => {
        this.posts = resp.data;
    }).catch(error => {
        console.log('从服务端加载文章数据失败');
    });
},

访问 posts 页面,对应的文章列表卡片视图渲染效果如下:

-w1157

说明后端接口返回测试数据成功。

下篇教程,我们将调整发布文章表单组件,完成文章详情浏览和编辑功能,并借着这些功能穿插 Vue 组件动画和过渡效果实现的演示。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 通过过滤器对 Vue 组件中的模型属性值进行格式化

>> 下一篇: 基于 Laravel + Vue 组件实现文章发布、编辑和浏览功能