LoginSignup
11

More than 3 years have passed since last update.

【Laravel】いろいろ見たけどリポジトリパターンの実装ができなかった初心者のためにとりあえず実装するまでをシンプルに書く

Last updated at Posted at 2020-10-12

3行で

  • UserのModelに紐づいたリポジトリパターンを実装する
  • コントローラではModelにタッチしないということを意識する
  • 5つのファイルをいじる

リポジトリファイルを作る

ディレクトリ /app の中に Repositories というディレクトリを作り、さらにその中に User というディレクトリを作り、この中にファイルを2つ作ります(この辺の構成は正直自由ですが)。

  • /app/Repositories/User/UserRepository.php(実装ファイル)
  • /app/Repositories/User/UserRepositoryInterface.php(インターフェイス)

この2つのファイルでModelを経由してDBにアクセスして、データを持ってきたりcreateしたりupdateしたりします。
今回はUser Modelに紐づくリポジトリパターンを作ります。つまりこれらを使ってUserのデータを持ってきたり更新したりします。コントローラではなく、これらのファイルで行うことになります。

1. 実装クラス

UserRepository.php
<?php

// Modelに紐づく2つのメソッド以外はコピペのような感覚で書いちゃって構わないです

namespace App\Repositories\User;

// Modelにアクセスする旨を書く
use App\User;

class UserRepository implements UserRepositoryInterface
{
  protected $user;

    /**
    * @param object $user
    */

  public function __construct(User $user)
  {
      $this->user = $user;
  }

  // 名前に紐づくUserのデータを1件持ってくる
  public function getUser($name)
  {
    return $this->user->where('name', $name)->first();
  }

  // 後述のコントローラから $request を受け取って、中に入った名前とメールアドレスでユーザーを作る
  public function createUser($request)
  {
    return $this->user->create([
      'name' => $request['name'],
      'email' => $request['email'],
    ]);
  }
}

その他のメソッドは上記を応用して書いてみてください!

2. インターフェース

UserRepositoryInterface.php
<?php

// 上の実装クラスに書いた、Modelに紐づく2つのメソッドを書いて使えるようにします

namespace App\Repositories\User;

interface UserRepositoryInterface
{
  public function getUser($name);

  public function createUser($request);
}

ServiceProviderに登録する

AppServiceProvider.php を編集する。
ここにリポジトリのファイルを使うために登録するイメージです。
もしエラーが出たら以下の記事も見てみてください。

【Laravel】リポジトリパターン実装におけるエラー Target [App\Repositories\UserRepositoryInterface] is not instantiable while building

AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */

    /**
     * Bootstrap any application services.
     *
     * @return void
     */

    public function boot()
    {
        //
    }

    // インターフェースと実装クラスを登録
    public function register()
    {
        // 本記事ではタッチしませんが記事用のリポジトリも登録しておきます
        $this->app->bind(
            \App\Repositories\Article\ArticleRepositoryInterface::class,
            \App\Repositories\Article\ArticleRepository::class
        );
        $this->app->bind(
            \App\Repositories\User\UserRepositoryInterface::class,
            \App\Repositories\User\UserRepository::class
        );
    }
}

コントローラでリポジトリを呼び出す

UserController.php
<?php

namespace App\Http\Controllers;

// リポジトリを使うと宣言
use App\Repositories\User\UserRepositoryInterface;

// コントローラではModelにタッチしない
// use App\Models\User;

use Illuminate\Http\Request;

class UserController extends Controller
{
    // リポジトリ
    protected $UserRepository;

    public function __construct(
      // リポジトリ
        UserRepositoryInterface $userRepository
    )
    {
      // リポジトリ
        $this->UserRepository = $userRepository;
    }

    // 中略

    public function show($name)
    {
        // リポジトリのメソッドに引数を渡して呼び出す
        $user = $this->UserRepository->getUser($name);

        return view('users.show', [
            'user' => $user,
        ]);
    }

    public function store($request)
    {
        // フォームから受け取った $request をリポジトリのメソッドに渡し、Userデータを作る
        $this->UserRepository->createUser($request);

        return redirect()->route('home');
    }
}

以上です。
データが渡っているかがわからない、うまくいかない場合は dd($request) などを使って検証してください!

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
11