1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

scopeプレフィックス付きのメソッド

1
Posted at

ローカルスコープはモデルのメソッドとして定義し、先頭に scope を付けます。Laravel は scopePopular のようなメソッドを見つけると、外からは popular() という名前で呼べるようにします 。

class User extends Model
{
	public function scopeActive($query)
	{
		return $query->where('active', 1);
	}
}

呼び出し側はこうです。

User::active()->get();

この active() 呼び出しは、内部的には Eloquent Builder に対してクエリ条件を追加しているだけです。スコープのメソッドは Builder を受け取り、Builder を返すのが基本です 。

Laravel 12 系では、#[Scope] 属性を使って scope プレフィックスなしで定義する方法も紹介されていますが、従来の scope* 方式は今でも使えます 。

モデルに書くメリット

条件をモデルに寄せると、同じ条件を何度も書かずに再利用できるのが大きな利点です 。また、where の塊がリポジトリやコントローラに散らばりにくくなり、User::active()->ofType('admin') のように読みやすいチェーンになります 。

さらに、モデルに「この集まりはどういう条件で取るか」という意味を閉じ込められるので、ドメインの意図が見えやすいです。active users や published articles のような概念が、そのままメソッド名になります 。

デメリット

一方で、モデルに条件を集めすぎると、モデルが肥大化しやすいです。検索条件、集計条件、管理画面用条件などを全部入れると、関連の薄いロジックまでモデルに混ざります 。

また、複雑な検索や複数テーブルをまたぐ条件は、スコープだけで表現すると読みにくくなることがあります。そういう場合は、モデルスコープよりもクエリオブジェクトやサービス層の方が適切なことがあります 。

リポジトリに直書きする場合との比較

観点 モデルのスコープ リポジトリに where 直書き
再利用性 高い。同じ条件をどこでも呼べる 低い。各メソッドで重複しやすい
可読性 ドメイン名で読める SQL 寄りで意図が見えやすいこともある
変更容易性 条件変更を一箇所に集約しやすい 変更箇所が散らばりやすい
複雑条件への向き不向き 単純な条件に強い 複雑な検索でも書き分けやすい
責務分離 ドメイン的な条件をモデルに寄せやすい データ取得の詳細をリポジトリに閉じやすい

書くときの注意点

スコープは「どこでも使える便利な共通条件」だけに絞るのが基本です。画面固有の条件や、一回しか使わない条件まで入れると、かえって見通しが悪くなります 。

スコープは 必ず Builder を返す ようにしてください。途中で get() や first() を呼ぶと、チェーンできなくなります 。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?