Day 4 - 介绍Laravel Eloquent ORM

前一篇介绍了如何运用 Laravel 框架设计模式规划大型专案,当中有提到Model,今天就来介绍这个Laravel Eloquent ORM.
开始前我们可以先把原先Laravel预设帮我们建立的migration和Model删除或是直接改动档案内容,才不会导致建立重复的档案

首先要知道每个资料表要对应一个Model,所以当我们要一个User table,可以直接这样下指令

$ sail artisan make:model User --migration

可以看到资料夹中建立了两个档案,

  1. 第一个是/database/migration中的
    2021_09_07_151450_create_users_table.php,migration指的就是资料库的版本控制,透过新增migration档案来操作资料库的新增、修改、删除,可以让我们就算不同人进行开发,也能确保资料库可以得到同步.

我们先在该档案的up()处输入我们想建立的栏位,范例为建立User资料表,栏位为使用者姓名、帐号、密码及启用状态,并在down()处设定删除此资料表

<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name')->comment('姓名');
            $table->string('account')->unique()->comment('帐号');
            $table->string('password')->comment('密码');
            $table->boolean('enabled')->default(true)->comment('启/停用');
            $table->timestamps();
        });
    }

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

当在建立时可以指定该栏位的状态,比方说唯一性、注解、预设值...,以下列出几个常见的

  • 此栏位的值必须为唯一
->unique()
  • 将此栏位加在特定栏位後面
->after('column')
  • 为栏位加上注解
->comment('my comment')
  • 为栏位指定默认值
->default($value)
  • 允许输入null
->nullable($value = true)

另外栏位的型态设定可以参考官方文件
接下来在comand-line下指令就可以建立出我们的table,会执行所有未完成的migration up()

$ sail artisan migrate

如果想回滚(rollback)资料库,则可以使用以下指令,范例为rollback到最近的一次迁移:

$ php artisan migrate:rollback --step=1
  1. 第二个档案是App/Models/User.php,我们依靠它来跟我们的Users资料表作沟通,
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 指定哪些栏位可以存取
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'account',
        'password',
    ];
    
    /**
     * 将资料作转换
     *
     * @var array
     */
    protected $casts = [
        'enabled' => 'boolean',
        'created_at' => 'datetime:Y-m-d H:i:s',
        'updated_at' => 'datetime:Y-m-d H:i:s'
    ];
}

以下介绍几个Model常见的属性

  • table
/**
 * 替 model 指定 table
 *
 * @var string
 */
 protected $table = 'users';

Tip: Model会预设去找Model name + s的资料表.


  • fillable
/**
 * 白名单,可以被批量赋值的栏位
 *
 * @var array
 */
 protected $fillable = ['name', 'age'];

  • guarded
/**
  * 黑名单,不可被批量赋值的栏位,当guarded为空阵列,代表所有栏位皆可赋值,fillable与guarded择一即可
  *
  * @var array
  */
 protected $guarded = ['id'];

详细说明:
由於我们有时候为求方便直接用以下方式进行写入,代表我们所有request代入的的payload都进行栏位的update,有些不想被修改的栏位就会被直接改动,例如id栏位,所以为了安全性要记得设定$fillable$guarded

$post = Post::create($request->all());

  • casts
/**
 * 将资料属性做转换
 *
 * @var array
 */
protected $casts = [
    'enabled' => 'boolean',
    'created_at' => 'datetime:Y-m-d H:i:s',
    'updated_at' => 'datetime:Y-m-d H:i:s'
];

详细说明:
当资料库的资料储存为0或1时,设定casts enabled为boolean,会将资料进行转换,当我们用Postman取出资料时,该值会转换为boolean,是非常方便的功能


介绍并设定完Model後,我们要在Repository使用它,Exception的部分我想另外写一篇文章介绍我们该怎麽处理它

<?php

namespace App\Repositories;

use Exception;
use App\Models\User;
use Illuminate\Support\Facades\Hash;

class UserRepository
{
    /**
     * 透过帐号搜寻特定使用者
     *
     * @param string $account 帐号
     * @return mixed
     */
    public function searchUserByAccount(string $account)
    {
        try {
            return User::select(['*'])
                ->where('account', $account)
                ->first();
        } catch (Exception $e) {
            dd($e);
        }
    }

    /**
     * 取得使用者
     *
     * @param int $limit 帐号
     * @return mixed
     */
    public function getUserPaginate(int $limit)
    {
        try {
            return User::paginate($limit);
        } catch (Exception $e) {
            dd($e);
        }
    }

    /**
     * 建立使用者
     *
     * @param array $data
     * @return mixed
     */
    public function registerAccount(string $name, string $account, string $password)
    {
        try {
            return User::create([
                'name' => $name,
                'account' => $account,
                'password' => Hash::make($password),
            ]);
        } catch (Exception $e) {
            dd($e);
        }
    }
}

如此一来我们已经完成Model和Repository的撰写,在後续文章会介绍如何在Service注入Repository,并使用这些function.


<<:  [Day 11] SRE - 事後检讨,拜托拜托让我吸个经验值

>>:  DAY19 浅谈深度学习

Re: 新手让网页 act 起来: Day03 - 再次了解React.createElement()

前言 在上一篇文章中我们简单的介绍到如何使用 React.createElement(),并搭配 R...

第 7 集:你有 Flex Style 吗?

此篇会简单介绍 FlexBox,以及 flex container 的排列方向设置、对齐设置技巧。 ...

[Day27]jsES6语法-解构(下)

我们也可以把解构方法用在物件里面,把 family 的值传到 Min ,并且用 Leo 的名称来代替...

android studio 30天学习笔记 -day 2 -icon

在这次的专案开发有用到vector asset,里面有一些可以应用在专案开发的向量图形,如以下图形:...

[Day 25] Android Studio 七日陨石开发:一起来布局 App 介面!

前言 昨天我们成功的运行了自己做的App。 但我们还有2个步骤要做: 布局App元件 实作App功能...