在大型的專案中使用 Laravel Eloquent ORM,某些工作可能會變得重複和繁瑣,所以本文為大家總結了 5 個很少人知道的小技巧,在開發過程中幫我節省了很多時間。下面就讓我們開始吧。
1. 快速生成 Model & Migration
這並不是一個很多人知道的小技巧,在 Laravel 文件中也沒有提到。下面我們以一個部落格為簡單的例子,為文章生成 Model 和 Migration。
1 2 |
$ php artisan make:migration create_posts_table $ php artisan make:model Post |
大部分人可能會按上面這樣做,其實這兩條命令可以合併為下面這一條:
1 |
$ php artisan make:model Post -m |
2. Eloquent 查詢 Scopes
還是以前面的部落格應用為例,假設我們的文章表有一個 is_published
欄位,其值為 0 或 1 (表示 False 或 True )。在部落格列表,我們希望使用者只能看到已經發布(published
)的文章,使用 Eloquent 我們如何過濾掉未釋出的文章呢?答案很明顯,需要在查詢語句中使用 where
條件:
1 |
Post::where('is_published', true)->get(); |
這當然可以,但如果我們想在其他地方重複使用這個程式碼段呢?這麼重複複製當然也可以實現,但為了符合 DRY 原則( Don’t repeat yourself ),我們可以使用 Eloquent 的查詢 Scope。在 Post 模型中建立 ascopePublished
方法:
1 2 3 4 5 6 7 |
class Post extends Model { public function scopePublished($query) { return $this->where('is_published', true); } } |
要獲取已釋出文章,我們只需簡單的呼叫如下命令:
1 |
Post::published()->get(); |
Eloquent 可以自己把它翻譯為 scopePublished
方法。Eloquent 模型中任何以 scope
開始是方法都被當做 Eloquent scope。
值得注意的是,Eloquent scope 的返回值必須是一個查詢生成器的例項,所以在 scope 中你不能呼叫 ->get()
或 ->paginate()
。
3. Accessors(訪問器)
在很多情況下,你可能需要訪問 Eloquent 模型在資料中並不存在,需要經過一定計算的屬性,但很抱歉。我們來看一個例子。假設現在有一個 User
表,它包含這樣兩個欄位:forenames
和 surname
。如果你想在檢視中顯示使用者全名的話,你不得不這麼做:
1 |
{{ $user->forenames . ' ' . $user->surname }} |
首先,我們的應用中可能有很多地方需要使用這段程式碼,一遍又一遍的輸入顯然很不實際。其次,呃,語法非常的醜陋且顯得格格不入。下面我們來看看如何通過訪問器(又稱屬性)使其變得更加整潔一些。我們在 User 模型中建立一個新的方法:
1 2 3 4 5 6 7 |
class User extends Model { public function getNameAttribute() { return $this->forenames . ' ' . $this->surname; } } |
同 Eloquent 識別 scope 一樣,任何以 get
和 Attribute
包裹起來的方法都會當做 Eloquent accesor(訪問器)。現在我們可以試著執行下面的程式碼段,它得到的結果和前面是相同的:
1 |
{{ $user->name }} |
這不僅可以重複使用,而且更容易輸入,並且更具有可讀性。
4. 動態方法名稱
……缺乏一個很好的術語。Eloquent 對於一些方法特別的聰明,如 where()
。看看下面的例子:
1 2 3 4 5 6 7 8 |
// Post::where('published', 1)->get(); Post::wherePublished(1)->get(); // Post::where('category', null)->get(); Post::whereNull('category')->get(); // Post::where('category', '!=', null)->get(); Post::whereNotNull('category')->get(); |
是不是更加的整潔?
5. 擴充套件訪問器
我們來擴充套件一下 #3。有時候,特別是使用 API 時,當我們使用 Eloquent 從資料庫獲取記錄時,需要對返回的結果集中新增一些訪問器(或者說屬性)。如果沒看明白的話,看看下面這個例子。當呼叫 User::find(1)
的時候,返回的結果看起來可能是下面這樣的:
1 2 3 4 5 6 7 8 |
{ id: 1, forenames: "Terry", surname: "Harvey", email: "contact@terryharvey.co.uk", created_at: "2016-05-02 21:27:58", updated_at: "2016-05-03 18:09:37", } |
這並沒有什麼問題,但如果我們想在其中顯示前面建立的 name
屬性呢?讓我們回到模型中新增 $appends
屬性:
1 2 3 4 |
class User extends Model { protected $appends = ['name']; } |
如果再次執行前面的程式碼,name
屬性被直接新增到了結果中。
1 2 3 4 5 6 7 8 9 |
{ id: 1, forenames: "Terry", surname: "Harvey", name: "Terry Harvey", email: "contact@terryharvey.co.uk", created_at: "2016-05-02 21:27:58", updated_at: "2016-05-03 18:09:37", } |