はじめに
この記事では、Laravelでプレゼンターを利用し、ビューのロジックを分離する実装例を解説します。
具体的にはモデルのプロパティに応じて画面の表示文言を切り替えるという要件を、ビュー側のif文ではなく、プレゼンターで実現します。
Before
@if($member->gender === 1)
<p>男性</p>
@elseif($member->gender === 2)
<p>女性</p>
@elseif($member->gender === 3)
<p>指定無し</p>
@endif
After
<p>{{ $member->genderIndication()) }}</p>
環境
- Laravel 5.5.45
1. 事前準備
1.1. プレゼンターの新規作成
<?php
namespace App\Presenters;
use Illuminate\Database\Eloquent\Model;
abstract class Presenter
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function __call($method, $args)
{
return call_user_func_array([$this->model, $method], $args);
}
public function __get($name)
{
return $this->model->$name;
}
}
1.2. traitの新規作成
モデルをプレゼンターでラップするため、traitを作成します。
<?php
namespace App\Traits;
use App\Presenters\Presenter;
trait PresenterBuildable
{
public function presenter() : Presenter
{
$name = (new \ReflectionClass($this))->getShortName();
$class = sprintf("App\Presenters\%sPresenter", $name);
return new $class($this);
}
}
1.3. モデルの編集
<?php
namespace App;
use App\Traits\PresenterBuildable; // 追加
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
use PresenterBuildable; // 追加
protected $fillable = [
'name',
'age',
'gender',
'memo'
];
}
1.4. コントローラーの編集
ビューへ渡すモデルのインスタンスに対して、->presenter()
を追加しています。
こうすることで、ビュー側で毎回->presenter()
を記述することなく、プレゼンターのメソッドを使用できるようになります。
public function show(Member $member){
return view('members.show')->with('member', $member->presenter());
2. モデル別のプレゼンターの作成とビューの編集
2.1. モデルに対応するプレゼンターの作成
genderIndication
メソッド内のロジックは、先ほどのビュー同様にif文での条件分岐でも構わないのですが、今回は連想配列を定義し、gender
プロパティの値をキーとして、それを取り出すロジックとしました。
<?php
namespace App\Presenters;
class MemberPresenter extends Presenter
{
public function genderIndication()
{
return [
1 => '男性',
2 => '女性',
3 => '指定無し',
][$this->gender];
}
}
2.2. ビューの編集
<p>{{ $member->genderIndication()) }}</p>
最後に
1.事前準備
に若干の手間はかかりましたが、以降は各モデルに対応するプレゼンターに随時必要なメソッドを作成していくだけとなります。
今回プレゼンターを利用することによって、以下の利点が得られたかと思います。
-
ビューからロジックを分離し、再利用性を高める
-
モデルとは別にプレゼンターを用意したことで、画面表示に関するメソッドをモデルから独立させられる
-
モデルをラップするので、ビュー側からはモデルのメソッドと同様に使用できる