LoginSignup
36
22

More than 3 years have passed since last update.

【Laravel】プレゼンターを使ってビューのロジックを分離する

Last updated at Posted at 2019-05-28

はじめに

この記事では、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. プレゼンターの新規作成

app/Presenters/Presenter.php

<?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を作成します。

app/Traits/PresenterBuildable.php
<?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. モデルの編集

app/Member.php
<?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()を記述することなく、プレゼンターのメソッドを使用できるようになります。

app/Http/Controllers/MemberController.php
    public function show(Member $member){
        return view('members.show')->with('member', $member->presenter());

2. モデル別のプレゼンターの作成とビューの編集

2.1. モデルに対応するプレゼンターの作成

genderIndicationメソッド内のロジックは、先ほどのビュー同様にif文での条件分岐でも構わないのですが、今回は連想配列を定義し、genderプロパティの値をキーとして、それを取り出すロジックとしました。

app/Presenters/MemberPresenter.php
<?php

namespace App\Presenters;

class MemberPresenter extends Presenter
{
    public function genderIndication()
    {
        return [
            1 => '男性',
            2 => '女性',
            3 => '指定無し',
        ][$this->gender];
    }
}

2.2. ビューの編集

resources/views/members/show.blade.php
<p>{{ $member->genderIndication()) }}</p>

最後に

1.事前準備に若干の手間はかかりましたが、以降は各モデルに対応するプレゼンターに随時必要なメソッドを作成していくだけとなります。

今回プレゼンターを利用することによって、以下の利点が得られたかと思います。

  • ビューからロジックを分離し、再利用性を高める

  • モデルとは別にプレゼンターを用意したことで、画面表示に関するメソッドをモデルから独立させられる

  • モデルをラップするので、ビュー側からはモデルのメソッドと同様に使用できる

参考

36
22
3

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
36
22