# 前言
學習一個框架, 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 deletedmodel
# 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() | 
留言