1. アクセサでデータを作成
DBに存在しないアトリビュートをJSONのレスポンスで吐き出しができます。ゲッターとセッターを使うのは元々可能ですけど、アクセサで作られるアトリビュートがデフォルトでJSONになりません。そういうときは$appends
が助けてくれます!
<?php
class Store extends Model
{
$appends = ['products_count']; // ← ここを追加すると
public function getProductsCountAttribute()
{
// 複数クエリーに気をつけてください :)
return $this->product()->count();
}
}
class StoresController extends Controller
{
public function index()
{
return Store::all();
// products_countも一緒に表示されます
}
}
2. クエリースコープ
複雑な条件があるとコードが汚くなる可能性が高くなりますね。それぞれのクエリーの条件をスコープにすれば、別々になるおまけに、メソッド名から理解できるようになります。
スコープを使って綺麗なクエリーを書きましょう!
<?php
// モバイルの大きな発売の取得
Order::bigSales()
->fromMobile()
->get();
// 先週モバイルで行われた1000円以上の発売の取得
Order::totalGreaterThan(1000)
->fromMobile()
->lastWeek()
->get();
class Order extends Model
{
public function scopeBigSales($query)
{
return $query->totalGreaterThan(5000);
}
public function scopeTotalGreaterThan($query, $total)
{
return $query->where('total', '>', $total);
}
public function scopeFromMobile($query)
{
return $query->whereIn('source', ['phone', 'tablet']);
}
public function scopeLastWeek($query)
{
return $query->where('created_at', Carbon::now()->subWeek());
}
}
3. グローバルスコープも可能です
ユーザーは自分のポストしか見れないとか?簡単です!
ログインしているユーザーのみの結果がほしい場合、グローバルスコープが有効です。
class Post extends Model
{
protected static function boot()
{
parent::boot();
static::addGlobalScope('my_posts', function(Builder $builder) {
// ログインしてるユーザーのみ
$builder->where('user_id', auth()->id());
});
}
}
一年以上前の古いデータを隠すとか?
class Order extends Model
{
protected static function boot()
{
parent::boot();
static::addGlobalScope('last_year_only', function(Builder $builder) {
// 去年から取得する
$builder->where('created_at', '>', Carbon::now()->subYear());
});
}
}
もちろん、古いデータが必要だったらとか、他のユーザーのポストが必要だったらとか、グローバルスコープを外すことができます。
// 今年のデータに限るスコープを外す
Order::withoutGlobalScope('last_year_only')->get();
// 全てのスコープを外す
Order::withoutGlobalScopes()->get();
4. イベントも簡単です!
Laravelが発火するイベントは下記のようです。
イベント名 | 説明 |
---|---|
creating | 作成するとき |
created | 作成したとき |
updating | 更新するとき |
updated | 更新したとき |
saving | 保存するとき(制作でも、更新でも) |
saved | 保存したとき(制作でも、更新でも) |
deleting | 削除するとき |
deleted | 削除したとき |
restoring | ソフト削除をレストアするとき |
restored | ソフト削除をレストアしたとき |
使い方もとても簡単です。グローバルスコープのように、boot()
で登録するといいです。
class Order extends Model
{
protected static function boot()
{
parent::boot();
static::creating(function ($order) { // 作成するときに
// falseをリターンしたら作成されません
return $order->isValid();
});
static::created(function ($order) { // 作成したときに
$order->sendOrderSubmittedEmail();
});
}
}
Special Thanks
ありがとうございます!! :D