# Eloquent 魔術函式
### 預先處理被異動的欄位資料
在使用 Eloquent 新增或異動資料時,我們可能想要對輸入的資料做預先的處理,我們可以使用 Laravel 提供的魔術函式 `setNameAttribute()` 去預先處理欄位資料。
如果我們要預先處理文章模型(Article)的發布時間欄位(published_at),我們的魔術函式就會是像:
~~~
class Article extends Model {
public function setPublishedAtAttribute($date) {
// 將傳入的 Y-m-d 時間設為 datetime 格式的現在時間
$this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d', $date);
// 將傳入的 Y-m-d 時間設為 datetime 格式的凌晨零時 00:00:00
$this->attributes['published_at'] = Carbon::parse($date);
}
}
~~~
> 魔術函式 `setNameAttribute()` 中,若遇到欄位名稱有底線的狀況,則將名稱設為駝峰式大小寫(Camel-Case),像是 `published_at` 則變成 `PublishedAt`
### 自定義 query 處理函式
假如我們要讀取發表的文章,但是發表的時間 `published_at` 必須過去的時間,設定於未來發表時間的文章不能被撈取出來,我們可以用這樣的方式去撈取:
~~~
// 取得已經發表的文章,依照發表時間降冪(Desc)排序
$article = \App\Article::latest('published_at')
->where('published_at', '<=', Carbon::now())
->get();
~~~
我們可以簡化這個 query,把它寫在 Model 用函式的方式做處理,這樣我們就可以用這樣去取得以發表的文章:
~~~
// 取得已經發表的文章,依照發表時間降冪(Desc)排序
$article = \App\Article::latest('published_at')
->published()
->get();
~~~
而 Model 裡面我們用 `scopeName` 魔術函式的方式去設定 `published()`:
~~~
class Article extends Model {
public function scopePublished($query) {
$query->where('published_at', '<=', Carbon::now());
}
}
~~~
若我們想要取得尚未被發表的文章資訊,我們模式函式也可以設定成:
~~~
class Article extends Model {
public function scopeUnpublished($query) {
$query->where('published_at', '>', Carbon::now());
}
}
~~~
這樣我們就可以用 `unpublished()` 去設定取得文章資訊了
~~~
// 取得已經發表的文章,依照發表時間降冪(Desc)排序
$article = \App\Article::latest('published_at')
->unpublished()
->get();
~~~
這樣的優點是:
1. 簡化程式的長度
1. 讓我們在不同的地方不需要寫同樣落落長的查詢
1. 讓查詢的可讀性增加,`published()` 與 `unpublish()` 我們不需要看查詢的語法條件就可以知道這個地方是要做什麼樣的查詢了
### 參考資料
- [Eloquent 101 - Laracast](https://laracasts.com/series/laravel-5-fundamentals/episodes/8)
- [Dates, Mutators, and Scopes - Laracast](https://laracasts.com/series/laravel-5-fundamentals/episodes/11)
- [Eloquent ORM - Laravel.tw](http://laravel.tw/docs/5.0/eloquent)
- 介紹
- 環境
- .env 檔案
- 資料庫
- Migration (遷移)
- Eloquent Model (模型)
- 設定
- 關聯
- 魔術函式
- 使用 Eloquent
- 常見問題
- 無法取得查詢 Log
- 使用大量資料的方式新增時無法新增
- 使用中繼模型繼承 Eloquent 模型造成無法使用大量資料新增
- PostgreSQL
- 安裝 PostgreSQL ODBC driver
- HTTP
- 請求
- 中介層 (Middleware)
- 視圖 (View)
- 服務
- 認證登入(Auth)
- 郵件(Mail)
- 使用 Gmail 寄信
- 使用 Mailgun 寄信
- 隊列(Queue)
- database
- 非同步(async)
- 輔助方法 (Helpers)
- 自定義輔助方法
- 單元測試 (Unit Test)
- Post CSRF 錯誤
- 錯誤與日誌
- 在單元測試顯示例外
- 日誌記錄層級
- 日誌巨集
- 加密
- 雜湊
- Elixir
- 使用 Elixir 合併 CSS 與 JS
- 設計模式
- 服務容器
- PSR
- Model 模型
- 學習資源
- 套件
- Debug
- Artisan tail
- 工具
- Carbon
- 設計模式
- 其他常見問題
- Call to undefined method getCachedCompilePath()
- 變更專案目錄名稱導致 View 無法讀取
- Laravel 5.1 目錄結構異動
- 學習資源
- 官方
- 社群
- 會議議程
- 工作
- 文件
- 文章
- 套件
- 服務工具
- 教學影片
- 教學網站
- 編輯開發
- 主機
- 成功案例