iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Software Development

全端開發包括測試自己一條龍!系列 第 4

Day 4 - 介紹Laravel Eloquent ORM

  • 分享至 

  • xImage
  •  

前一篇介紹了如何運用 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 3 - 如何運用Laravel框架設計模式規劃大型專案
下一篇
Day 5 - 使用JWT Token幫Laravel 8.0做Authentication
系列文
全端開發包括測試自己一條龍!10
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言