# 前言
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
# Defining Models
以下的 Laravel command 的意思是?
- Example:
php artisan make:model Flight
- Answer:
建立一個名為 Flight 的 model
以下的 Laravel command 的意思是?
- Example:
php artisan make:model Flight --migration
php artisan make:model Flight -m - Answer:
// 建立一個名為 Flight 的 model, 並建立其 migration
php artisan make:model Flight --migration
// 同上
php artisan make:model Flight -m
以下的 Laravel command 的意思是?
- Example:
php artisan make:model Flight --factory
php artisan make:model Flight -f
php artisan make:model Flight --seed
php artisan make:model Flight -s
php artisan make:model Flight --controller
php artisan make:model Flight -c
php artisan make:model Flight -mfsc - Answer:
// 建立 Flight model, 並建立其 Factory
php artisan make:model Flight --factory
// 同上
php artisan make:model Flight -f
// 建立 Flight model, 並建立其 seeder
php artisan make:model Flight --seed
// 同上
php artisan make:model Flight -s
// 建立 Flight model, 並建立其 controlelr
php artisan make:model Flight --controller
// 同上
php artisan make:model Flight -c
// 建立 Flight model, 並建立其 migraiton, factory, seeder, 以及 controller
php artisan make:model Flight -mfsc
# Eloquent Model Conventions
Laravel 中, 假設 model name 為 AirTrafficController, 根據 Laravel Model Convention, table name 應為?
air_traffic_controllers
# Table Names
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
protected $table = 'my_flights';
} - Answer:
指定該 model 所對應的 table
# Primary Keys
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
protected $primaryKey = 'flight_id';
} - Answer:
primary key 預設為id
, 可以特別指定
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
public $incrementing = false;
} - Answer:
Laravel 預設 primary key 為 id, 且為 auto-incrementing, 會 cast 成 int, 若要使用 non-numeric 或 non-incrementing 的 primary key 的話, 要特別指定為 false
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
protected $keyType = 'string';
} - Answer:
Laravel 預設 primary key 為 id, 且為 auto-incrementing, 會 cast 成 int, 若 primary key 不是 int, 需特別指定 type
# Timestamps
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
public $timestamps = false;
} - Answer:
Laravel Eloquent 預設會自動管理created_at
以及updated_at
欄位, 若不需 Eloquent 自動管理, 可設為 false
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
protected $dateFormat = 'U';
} - Answer:
Laravel 預設 timestamps 有其固定格式, 可特別指定格式, 格式決定儲存在資料庫中的格式以及 serialized 之後的格式
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
} - Answer:
Laravel 中, 預設儲存 timestamps 的 column 分別是 created_at 以及 updated_at, 可使用以上 example 來自定義
# Database Connection
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
protected $connection = 'connection-name';
} - Answer:
Laravel 中, Eloquent Model 會使用預設的 Database connection, 可使用上面的 example 自定義
# Default Attribute Values
以下的 Laravel example code 的意思是?
- Example:
<?php
class Flight extends Model
{
protected $attributes = [
'delayed' => false,
];
} - Answer:
設定 Eloquent Model attribute 的預設值
# Retrieving Models
# Adding Additional Constraints
以下的 Laravel example code 的意思是?
- Example:
<?php
$flights = App\Models\Flight::all();
foreach ($flights as $flight) {
echo $flight->name;
} - Answer:
all() 可取得該 model 的所有 records, 也可使用 query constraints 之後, 使用 get() 取得結果
以下的 Laravel example code 的意思是?
- Example:
<?php
$flights = App\Models\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get(); - Answer:
where()->orderBy()->take() 為 constraints, 最後使用 get() 取得資料, 若無 constraints, 可直接使用 all() 取得資料
# Refreshing Models
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::where('number', 'FR 900')->first();
$freshFlight = $flight->fresh(); - Answer:
fresh() 會從 model 重新取得資料, 不影響 $flight 的內容
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::where('number', 'FR 900')->first();
$flight->number = 'FR 456';
$flight->refresh();
$flight->number; // "FR 900" - Answer:
refresh() 會使用 fresh() 取得的 data 將原本的替換掉, 包括 relationship
# Collections
以下的 Laravel example code 的意思是?
- Example:
<?php
$flights = $flights->reject(function ($flight) {
return $flight->cancelled;
}); - Answer:
將 cancelled 的 model 從 $flights 這個 collection 中移除, 並取代 $flights
也可使用<?php
$flights->forget(function ($flight) {
return $flight->cancelled;
})
以下的 Laravel 中, 可以 foreach collection 嗎?
可以
# Chunking Results
以下的 Laravel example code 的意思是?
- Example:
<?php
Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
}); - Answer:
會將 collections 分成 1 個 chunk 200 筆資料, 所以共有幾個 chunk 視乎該 collection 共有幾筆資料, 再將每個 chunk 丟入 closure 執行, 如此一來, 當處理資料數量龐大的 collection 時, 可節省記憶體單次調用量
以下的 Laravel example code 的意思是?
- Example:
<?php
Flight::where('departed', true)->chunkById(200, function ($flights) {
$flights->each->update(['departed' => false]);
}); - Answer:
一次只取 200 筆 update 以節省 memory, chunkById 會記住上一次 chunk 的 last_id, 並加上 orderById, 下一次只會從 last_id 之後取值; 若只使用 chunk 的話, 會是 offset … limit …, 後者遇到數據量大時, 效能會很差, 前者可以很明顯地增進效能
# Advanced Subqueries
以下的 Laravel example code 的意思是?
- Example:
<?php
return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
])->get(); - Answer:
<?php
// 新增 last_flight column, 其值為 query Flight table 得來
return Destination::addSelect(['last_flight' => Flight::select('name')
// 這行主要定義, 哪些 last_flight 會對應到哪一個 Destination row
->whereColumn('destination_id', 'destinations.id')
// 依照 arrived_at 排序
->orderBy('arrived_at', 'desc')
// 只取一筆, 即最近的航班
->limit(1)
])->get();
# Retrieving Single Models / Aggregates
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::find(1);
$flight = App\Models\Flight::where('active', 1)->first();
$flight = App\Models\Flight::firstWhere('active', 1); - Answer:
<?php
// 取得符合 primary key 的 model
$flight = App\Models\Flight::find(1);
// 取得符合 where constraint 的第一個 model
$flight = App\Models\Flight::where('active', 1)->first();
// where('active', 1)->first() 的縮寫
$flight = App\Models\Flight::firstWhere('active', 1);
以下的 Laravel example code 的意思是?
- Example:
<?php
$flights = App\Models\Flight::find([1, 2, 3]); - Answer:
取得 primary key 符合 array 的 model
以下的 Laravel example code 的意思是?
- Example:
<?php
$model = App\Models\Flight::where('legs', '>', 100)
->firstOr(['id', 'legs'], function () {
// ...
}); - Answer:
取得符合 (‘legs’, ‘>’, 100) 條件的第一個 model 的 ‘id’ 及 ‘legs’ column, 如果該 model 不可得, 則執行 closure 內的動作
# Not Found Exceptions
以下的 Laravel example code 的意思是?
- Example:
<?php
$model = App\Models\Flight::findOrFail(1);
$model = App\Models\Flight::where('legs', '>', 100)->firstOrFail(); - Answer:
<?php
// 取得 primary key 為 1 的 model, 如果沒找到, 則 throw 'ModelNotFoundException'
// 如果該 exception 沒有被 caught, 則會回傳 404 給 user
$model = App\Models\Flight::findOrFail(1);
// 取得符合 ('legs', '>', 100) 條件的第一個 model, 如果沒找到, 則 throw 'ModelNotFoundException'
// 如果該 exception 沒有被 caught, 則會回傳 404 給 user
$model = App\Models\Flight::where('legs', '>', 100)->firstOrFail();
# Retrieving Aggregates
以下的 Laravel example code 的意思是?
- Example:
<?php
$count = App\Models\Flight::where('active', 1)->count();
$max = App\Models\Flight::where('active', 1)->max('price'); - Answer:
<?php
// 取得符合 where('active', 1) 條件的 model 數量
$count = App\Models\Flight::where('active', 1)->count();
// 取得符合 where('active', 1) 條件的 model 中, price column 的最大值
$max = App\Models\Flight::where('active', 1)->max('price');
# Inserting & Updating Models
# Inserts
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Http\Controllers;
class FlightController extends Controller
{
public function store(Request $request)
{
// Validate the request...
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
} - Answer:
從 $request 取得 name, 在 assign 到 $flight model 的 name attribute, 在執行 save() 存到資料庫
created_at 以及 updated_at 會自動建立
# Updates
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save(); - Answer:
取得 primary key 為 1 的 model, 再用 save() 更新其 name attribute, updated_at 欄位會自動更新
# Mass Updates
以下的 Laravel example code 的意思是?
- Example:
<?php
App\Models\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]); - Answer:
取得符合 where(‘active’, 1), 以及 where(‘destination’, ‘San Diego’) 的 models, 並更新 delayed column 為 1
Laravel 中, 當使用 Eloquent 實施 mass update 時, model events 像是 saving, saved, updating, updated 會被觸發嗎?
不會
# Examining Attribute Changes
以下的 Laravel example code 的意思是?
- Example:
<?php
$user = User::create([
'first_name' => 'Taylor',
'last_name' => 'Otwell',
'title' => 'Developer',
]);
$user->title = 'Painter';
$user->isDirty(); // true or false
$user->isDirty('title'); // true or false
$user->isDirty('first_name'); // true or false
$user->isClean(); // true or false
$user->isClean('title'); // true or false
$user->isClean('first_name'); // true or true
$user->save();
$user->isDirty(); // true or false
$user->isClean(); // true or false - Answer:
<?php
$user = User::create([
'first_name' => 'Taylor',
'last_name' => 'Otwell',
'title' => 'Developer',
]);
// 這裡變更了 $user model 的 title attribute, 但尚未更動資料庫
$user->title = 'Painter';
// $user model 的 title attribute 變了, 所以 true
$user->isDirty(); // true
// 同上
$user->isDirty('title'); // true
// first_name attribute 並未更動, 所以 false
$user->isDirty('first_name'); // false
// $user model 已有變更, 所以非 clean
$user->isClean(); // false
// title attribute 已變更, 所以非 clean
$user->isClean('title'); // false
// first_name attribute 並未更動, 所以 clean
$user->isClean('first_name'); // true
// 這邊才真正更動資料庫
$user->save();
// 更動後, model 跟資料庫已同步, 所以 isDirty 為 false
$user->isDirty(); // false
// 更動後, model 跟資料庫已同步, 所以是 clean 的
$user->isClean(); // true
以下的 Laravel example code 的意思是?
- Example:
<?php
$user = User::create([
'first_name' => 'Taylor',
'last_name' => 'Otwell',
'title' => 'Developer',
]);
$user->title = 'Painter';
$user->save();
$user->wasChanged(); // true or false
$user->wasChanged('title'); // true or false
$user->wasChanged('first_name'); // true or false - Answer:
<?php
$user = User::create([
'first_name' => 'Taylor',
'last_name' => 'Otwell',
'title' => 'Developer',
]);
// 這邊更動了資料庫
$user->title = 'Painter';
$user->save();
// 資料庫在當次 request cycle 有更動, 故為 true
$user->wasChanged(); // true
// title 有更動, 故為 true
$user->wasChanged('title'); // true
// first_name 並沒有更動, 所以為 false
$user->wasChanged('first_name'); // false
以下的 Laravel example code 的意思是?
- Example:
<?php
$user = User::find(1);
$user->name; // John
$user->email; // john@example.com
$user->name = "Jack";
$user->name; // Jack
$user->getOriginal('name'); // 這裡是?
$user->getOriginal(); // 這裡是? - Answer:
<?php
$user = User::find(1);
$user->name; // John
$user->email; // john@example.com
// 這裡變更了 $user model, 但尚未更動資料庫
$user->name = "Jack";
$user->name; // Jack
// 取得變更前的 $user model 的 name attribute
$user->getOriginal('name'); // John
// 取得變更前的 $user model
$user->getOriginal(); // 為更動前的 model array
# Mass Assignment
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
class Flight extends Model
{
protected $fillable = ['name'];
} - Answer:
允許 name column 可以批量 assign, 防止有心人士自帶預料外的參數 assign 到預料外的欄位
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::create(['name' => 'Flight 10']); - Answer:
建立一筆資料, 並取得該 model
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight->fill(['name' => 'Flight 22']); - Answer:
assign ‘Flight 22’ 到 $flight model 的 name attribute
相當於 $flight->name = ‘Flight 22’;
以下的 Laravel example code 的意思是?
- Example:
<?php
$fillable = [
'options->enabled',
]; - Answer:
允許 nested JSON attribute “options->enabled” 可被批量 assign
以下的 Laravel example code 的意思是?
- Example:
<?php
protected $guarded = []; - Answer:
該 model 內的所有 attribute 都允許 mass assignment
# Other Creation Methods
# firstOrCreate
/ firstOrNew
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::firstOrCreate(['name' => 'Flight 10']);
$flight = App\Models\Flight::firstOrCreate(
['name' => 'Flight 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
$flight = App\Models\Flight::firstOrNew(['name' => 'Flight 10']);
$flight = App\Models\Flight::firstOrNew(
['name' => 'Flight 10'],
['delayed' => 1, 'arrival_time' => '11:30']
); - Answer:
<?php
// 使用條件 ['name' => 'Flight 10'] 從資料庫尋找, 若找到則回傳該 model,
// 若沒找到, 則使用 ['name' => 'Flight 10'] 建立該筆資料並回傳該 model
$flight = App\Models\Flight::firstOrCreate(['name' => 'Flight 10']);
// 使用條件 ['name' => 'Flight 10'] 從資料庫尋找, 若找到則回傳該 model,
// 若沒找到, 則使用 ['name => 'Flight 10', 'delayed' => 1, 'arrival_time' => '11:30']
// 建立該筆資料並回傳該 model
$flight = App\Models\Flight::firstOrCreate(
['name' => 'Flight 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
// 使用條件 ['name' => 'Flight 10'] 從資料庫尋找, 若找到則回傳該 model,
// 若沒找到, 則使用 ['name' => 'Flight 10'] 回傳並建立該 model, 但尚未
// 更新資料庫
$flight = App\Models\Flight::firstOrNew(['name' => 'Flight 10']);
// 使用條件 ['name' => 'Flight 10'] 從資料庫尋找, 若找到則回傳該 model,
// 若沒找到, 則使用 ['name => 'Flight 10', 'delayed' => 1, 'arrival_time' => '11:30']
// 建立該 model, 但尚未更新資料庫
$flight = App\Models\Flight::firstOrNew(
['name' => 'Flight 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
# updateOrCreate
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
); - Answer:
<?php
// 使用條件 ['departure' => 'Oasland', 'destination' => 'San Diego'] 尋找
// 如果有找到, 更新 ['price' => 99, 'discounted' => 1], 如果沒找到, merge 上面
// 兩個 array 並建立該筆資料
$flight = App\Models\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
以下的 Laravel example code 的意思是?
- Example:
<?php
App\Models\Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']); - Answer:
<?php
// 尋找第一個 arg 中的兩筆 record [['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], [array 2]]
// 如果沒找到, 則以上面 array 中的資料建立, 如果有找到, 即 duplicate record, 那就更新第三個 arg 中的
// price column, 則判斷是否 exist 的 unique 欄位為第二個 array 中的 ['departure', 'destination']
App\Models\Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
# Deleting Models
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight = App\Models\Flight::find(1);
$flight->delete(); - Answer:
取得 primary key 為 1 的 model, 並 delete
# Deleting An Existing Model By Key
以下的 Laravel example code 的意思是?
- Example:
<?php
App\Models\Flight::destroy(1);
App\Models\Flight::destroy(1, 2, 3);
App\Models\Flight::destroy([1, 2, 3]);
App\Models\Flight::destroy(collect([1, 2, 3])); - Answer:
<?php
// 刪除 primary key 為 1 的 model
App\Models\Flight::destroy(1);
// 同上
App\Models\Flight::destroy(1, 2, 3);
// 同上
App\Models\Flight::destroy([1, 2, 3]);
// 同上
App\Models\Flight::destroy(collect([1, 2, 3]));
以下的 Laravel example code, deleting
以及 deleted
event 會被觸發嗎?
- Example:
<?php
App\Models\Flight::destroy(1);
App\Models\Flight::destroy(1, 2, 3);
App\Models\Flight::destroy([1, 2, 3]);
App\Models\Flight::destroy(collect([1, 2, 3])); - Answer:
會的, 因為 destroy 會分別載入每個 model, 並呼叫 delete method
# Deleting Models By Query
以下的 Laravel example code 的意思是?
- Example:
<?php
$deletedRows = App\Models\Flight::where('active', 0)->delete(); - Answer:
刪除符合 where(‘active’, 0) 的 model
以下的 Laravel example code, deleting
以及 deleted
event 會被觸發嗎?
- Example:
<?php
$deletedRows = App\Models\Flight::where('active', 0)->delete(); - Answer:
不會, 因為實際上 model 並沒有被 retrieve
# Soft Deleting
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
use SoftDeletes;
} - Answer:
啟用 soft delete, 啟用後當執行 delete(), model 並不會真正被刪除, 而是會在 deleted_at column 增加一筆時間, 如果 deleted_at column 不是 null, 那就代表該筆資料已被 soft deleted
以下的 Laravel example code 的意思是?
- Example:
<?php
public function up()
{
Schema::table('flights', function (Blueprint $table) {
$table->softDeletes();
});
}
public function down()
{
Schema::table('flights', function (Blueprint $table) {
$table->dropSoftDeletes();
});
} - Answer:
<?php
public function up()
{
// 增加 deleted_at column
Schema::table('flights', function (Blueprint $table) {
$table->softDeletes();
});
}
public function down()
{
// 刪除 deleted_at column
Schema::table('flights', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
以下的 Laravel example code 的意思是?
- Example:
<?php
if ($flight->trashed()) {
//
} - Answer:
確認該 model 是否被 soft deleted
# Querying Soft Deleted Models
# Including Soft Deleted Models**
以下的 Laravel example code 的意思是?
- Example:
<?php
$flights = App\Models\Flight::withTrashed()
->where('account_id', 1)
->get(); - Answer:
當 model 被 soft deleted, 預設會被自動從 query 結果中排除, 如果要取得 soft deleted 的 model, 可以使用withTrashed()
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight->history()->withTrashed()->get(); - Answer:
取得 $flight model 的所有 history relation model, 包含 soft deleted
# Retrieving Only Soft Deleted Models
以下的 Laravel example code 的意思是?
- Example:
<?php
$flights = App\Models\Flight::onlyTrashed()
->where('airline_id', 1)
->get(); - Answer:
只取得符合 where(‘airline_id’, 1) 條件的soft deleted
model
# Restoring Soft Deleted Models
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight->restore(); - Answer:
將 $flight soft deleted model 復原, 換言之, 將 deleted_at column 設為 null
以下的 Laravel example code 的意思是?
- Example:
<?php
App\Models\Flight::withTrashed()
->where('airline_id', 1)
->restore(); - Answer:
restore 符合 where(‘airline_id’, 1) 的所有 model, 即把 deleted_at column 設為 null
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight->history()->restore(); - Answer:
restore $flight model 的 relation history 上的所有 soft deleted model
# Permanently Deleting Models
以下的 Laravel example code 的意思是?
- Example:
<?php
$flight->forceDelete();
$flight->history()->forceDelete(); - Answer:
<?php
// 強制刪除 $flight, 即真正的刪除這筆資料
$flight->forceDelete();
// 強制刪除 relation history 上的所有 model, 這裡不包含 soft-deleted
// 如果要取得 soft-deleted 需加上 withTrashed()
$flight->history()->forceDelete();
# Replicating Models
以下的 Laravel example code 的意思是?
- Example:
<?php
$shipping = App\Models\Address::create([
'type' => 'shipping',
'line_1' => '123 Example Street',
'city' => 'Victorville',
'state' => 'CA',
'postcode' => '90001',
]);
$billing = $shipping->replicate()->fill([
'type' => 'billing'
]);
$billing->save(); - Answer:
<?php
// 建立一筆資料, 並 assign 到 $shipping
$shipping = App\Models\Address::create([
'type' => 'shipping',
'line_1' => '123 Example Street',
'city' => 'Victorville',
'state' => 'CA',
'postcode' => '90001',
]);
// 複製 $shipping model, 將 type 替換為 'billing', 並 assign 到 $billing
// replicate 只是複製 model, 並未真正變動資料庫
$billing = $shipping->replicate()->fill([
'type' => 'billing'
]);
// 將 $billing 真正的存進資料庫
$billing->save();
# Query Scopes
Laravel 中, 當我新增 global scope constraint 時, 需要考慮到 soft-deleted 嗎?
不需要, Laravel 會自動處理好
# Global Scopes
# Writing Global Scopes
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class AgeScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where('age', '>', 200);
}
} - Answer:
新增一個 global scope constraint, 可以在 model 的 booted method 中加入各種新增的 global scope constraint, 加入後, 該 model 取得的 query 都會自動附加 where(‘age’, ‘>’, 200) constraint
# Applying Global Scopes
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use App\Scopes\AgeScope;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected static function booted()
{
static::addGlobalScope(new AgeScope);
}
} - Answer:
在 model 的 booted method 中, 可以將客制好的 global scope constraintAgeScope
附加到該 model, 如此一來, 之後使用 User model 的 query builder 都會自動附加AgeScope
所定義的 constraint
# Anonymous Global Scopes
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected static function booted()
{
static::addGlobalScope('age', function (Builder $builder) {
$builder->where('age', '>', 200);
});
}
} - Answer:
利用 closure 來附加 global scope constraint, 這樣就不必另外定義一個 scope class, 適用於較簡單的 global scope
# Removing Global Scopes
以下的 Laravel example code 的意思是?
- Example:
<?php
User::withoutGlobalScope(AgeScope::class)->get(); - Answer:
從當次 query 的結果中, 移除AgeScope
這個 global scope constraints
以下的 Laravel example code 的意思是?
- Example:
<?php
User::withoutGlobalScope('age')->get(); - Answer:
從當次 query 的結果中, 移除age
這個 global scope constraints, age 為 closure 方式直接在 model 的 booted method 中定義的
以下的 Laravel example code 的意思是?
- Example:
<?php
User::withoutGlobalScopes()->get();
User::withoutGlobalScopes([
FirstScope::class, SecondScope::class
])->get(); - Answer:
<?php
// 從當次 User model 的 query 當中移除所有 global scopes
User::withoutGlobalScopes()->get();
// 從當次 User model 的 query 當中移除 array 中的 global scope
User::withoutGlobalScopes([
FirstScope::class, SecondScope::class
])->get();
# Local Scopes
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeActive($query)
{
return $query->where('active', 1);
}
} - Answer:
定義 local scope, 簡單來說, 當我使用 $query->popular() 就會等於 $query->where(‘votes’, ‘>’, 100), 而 $query->active() 便會等於 $query->where(‘active’, 1)
# Utilizing Local Scope
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeActive($query)
{
return $query->where('active', 1);
}
}
$users = App\Models\User::popular()->active()->orderBy('created_at')->get(); - Answer:
popular() 以及 active() 為 local scope, 會使用定義於該 local scope 內 query
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeActive($query)
{
return $query->where('active', 1);
}
}
$users = App\Models\User::popular()->orWhere(function (Builder $query) {
$query->active();
})->get(); - Answer:
相當於$query->where(...)->orWhere(...)
constraints, 只不過對象換成了 local scope, 像是$query->popular()->orActive()
, 注意後者語法只是比喻, Laravel 目前沒有提供這樣的用法, 也可使用orWhere->
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeActive($query)
{
return $query->where('active', 1);
}
}
$users = App\Models\User::popular()->orWhere->active()->get(); - Answer:
相當於$query->where(...)->orWhere(...)
constraints, 只不過對象換成了 local scope, 像是$query->popular()->orActive()
, 注意後者語法只是比喻, Laravel 目前沒有提供這樣的用法, 也可使用 closure 方式帶入 orWhere()
# Dynamic Scopes
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function scopeOfType($query, $type)
{
return $query->where('type', $type);
}
}
$users = App\Models\User::ofType('admin')->get(); - Answer:
dynamic scopes 概念, 可以動態的帶入參數到 scope 內, 所以User::ofType('admin')->get()
, 就相當於User::where('type', 'admin')->get()
# Comparing Models
以下的 Laravel example code 的意思是?
- Example:
<?php
if ($post->is($anotherPost)) {
//
} - Answer:
比較兩個 model 是否有相同的 primary_key, table, database connection
以下的 Laravel example code 的意思是?
- Example:
<?php
if ($post->author()->is($user)) {
//
} - Answer:
比較 $post model 的 author relation model 是否跟 $user model 有相同的 primary_key, table, database connection
# Events
Laravel Eloquent Model 中, retrieved event 什麼時候會被觸發?
當有一個現存 model 從 database 被 retrieve 時
Laravel Eloquent Model 中, creating/created event 什麼時候會被觸發?
當一個 model 第一次被儲存在資料庫時, 只有第一次會觸發
Laravel Eloquent Model 中, updating/updated event 什麼時候會被觸發?
當現存的 model 被更新且呼叫 save()
Laravel Eloquent Model 中, saving/saved event 什麼時候會被觸發?
當 model 被建立或更新都會觸發
# Using Closures
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected static function booted()
{
static::created(function ($user) {
//
});
}
} - Answer:
使用 closure 來定義當 created model event 被觸發後所做的事
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use function Illuminate\Events\queueable;
class User extends Model
{
protected static function booted()
{
static::created(queueable(function ($user) {
//
}));
}
} - Answer:
使用 closure 來定義當 created model event 被觸發後所做的事, 並 queue 被觸發的 closure listener
# Observers
以下的 Laravel example command 的意思是?
- Example:
php artisan make:observer UserObserver --model=User
- Answer:
建立一個 observer, 名為 UserObserver, 對應的 model 為 User model, 可定義一系列 User model 的各種 model event 的 Listener
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
public function created(User $user)
{
//
}
public function updated(User $user)
{
//
}
public function deleted(User $user)
{
//
}
public function forceDeleted(User $user)
{
//
}
} - Answer:
<?php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
// 當 created model event 被觸發後要做的事
public function created(User $user)
{
//
}
// 當 updated model event 被觸發後要做的事
public function updated(User $user)
{
//
}
// 當 deleted model event 被觸發後要做的事
public function deleted(User $user)
{
//
}
// 當 forceDeleted model event 被觸發後要做的事
public function forceDeleted(User $user)
{
//
}
}
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Providers;
use App\Observers\UserObserver;
use App\Models\User;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
//
}
public function boot()
{
User::observe(UserObserver::class);
}
} - Answer:
在 AppServiceProvider 中註冊 UserObserver, 註冊後 UserObserver 後, 定義於 UserObserver 的 Listener 會開始監聽 User model event
# Muting Events
以下的 Laravel example code 的意思是?
- Example:
<?php
use App\Models\User;
$user = User::withoutEvents(function () use () {
User::findOrFail(1)->delete();
return User::find(2);
}); - Answer:
withoutEvent method 只接受 closure 為參數, 在這個 closure 內執行的任何 code 都不會觸發 model event
範例中刪除 primary key 為 1 的 User model, 但不會觸發任何 model event
# Saving A Single Model Without Event
以下的 Laravel example code 的意思是?
- Example:
<?php
$user = User::findOrFail(1);
$user->name = 'Victoria Faith';
$user->saveQuietly(); - Answer:
修改 primary key 為 1 的 User model, 且不觸發任何 model event
# Additional
在 Laravel 中, 如何得到與該 model 相關的 table 的名字?
model->getTable() |
留言