#08 Laravel基礎
スコープとアクセサー
スコープとは
スコープ? Eloquentのクエリ条件を再利用可能なメソッドにする仕組み。`scopeActive()`のように定義し、`User::active()->get()`のように使う。 は、よく使うクエリ条件をEloquentモデルのメソッドとして定義する仕組みです。同じ where 条件をコントローラーのあちこちに書く代わりに、1か所にまとめられます。
ローカルスコープ
scope というプレフィックスを付けたメソッドを定義します。
<?php
// 📁 app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// スコープ名は "scope" + パスカルケースで命名
public function scopePublished($query)
{
return $query->where('status', 'published');
}
public function scopeRecent($query, int $days = 30)
{
return $query->where('created_at', '>=', now()->subDays($days));
}
}
呼び出し方
// 📁 app/Http/Controllers/PostController.php
// published() と recent() スコープを組み合わせる
$posts = Post::published()->recent(7)->latest()->paginate(15);
scope プレフィックスを除いたメソッド名(published、recent)でチェーンできます。
グローバルスコープ
ある条件を常に自動で適用したい場合はグローバルスコープを使います。
php artisan make:scope ActiveUserScope
<?php
// 📁 app/Models/Scopes/ActiveUserScope.php
namespace App\Models\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class ActiveUserScope implements Scope
{
public function apply(Builder $builder, Model $model): void
{
$builder->where('is_active', true);
}
}
モデルに登録します。
<?php
// 📁 app/Models/User.php
use App\Models\Scopes\ActiveUserScope;
class User extends Model
{
protected static function booted(): void
{
static::addGlobalScope(new ActiveUserScope());
}
}
これで User::all() は常に WHERE is_active = 1 が付くようになります。
グローバルスコープを外したい場合:
// このクエリだけグローバルスコープを無効化
$allUsers = User::withoutGlobalScope(ActiveUserScope::class)->get();
アクセサー
アクセサー? モデルの属性値を取得するときに自動で変換処理を行う仕組み。たとえば`full_name`属性を姓名の結合で返すようにできる。 は、モデルの属性値を取得するときに自動で変換する仕組みです。
Laravel 9以降の書き方(Attribute クラスを使う):
<?php
// 📁 app/Models/User.php
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Model
{
// フルネームを返す仮想属性
protected function fullName(): Attribute
{
return Attribute::make(
get: fn () => "{$this->last_name} {$this->first_name}",
);
}
// メールアドレスを常に小文字で返す
protected function email(): Attribute
{
return Attribute::make(
get: fn ($value) => strtolower($value),
);
}
}
使い方:
$user = User::find(1);
echo $user->full_name; // → "山田 太郎"(スネークケースでアクセス)
echo $user->email; // → 常に小文字
ミューテーター(保存時の変換)
保存するときに変換するには set も指定します。
<?php
// 📁 app/Models/User.php
protected function password(): Attribute
{
return Attribute::make(
set: fn ($value) => bcrypt($value), // ← 保存前に自動でハッシュ化
);
}
// パスワードを代入するだけで自動でハッシュ化される
$user->password = 'secret123';
$user->save();
キャスト(型の変換)
$casts プロパティを使うと、カラムの型を自動で変換できます。
<?php
// 📁 app/Models/Post.php
class Post extends Model
{
protected $casts = [
'published_at' => 'datetime', // Carbon オブジェクトに変換
'metadata' => 'array', // JSON ↔ 配列に自動変換
'is_featured' => 'boolean', // 整数 ↔ bool に変換
];
}
$post->published_at->format('Y年m月d日'); // Carbon メソッドが使える
$post->metadata['key']; // 配列としてアクセス(DBにはJSONで保存)
まとめ
- ローカルスコープ:
scopeXxx()でよく使うwhere条件を再利用できる - グローバルスコープ:常に適用される条件を自動化できる
- アクセサー:取得時に属性値を変換する(
Attribute::make(get: ...)) - ミューテーター:保存時に属性値を変換する(
Attribute::make(set: ...)) $casts:JSONや日時など型の自動変換に使う
次回はEloquentのmanyToManyリレーションとポリモーフィックリレーションを学びます。