PHP

Laravel リポジトリパターン

Laravel

 

リポジトリパターンのスタイルにするのが勝ちパターンみたいなので覚える。

確かにわかりやすいし、テストしやすくなる。

  • テストの切り分け
    本来はコントローラのテストだけ、DBのテストと別でテストできるものでなくてはならない

 

下記サイトを参考にやってみました。
https://www.ritolab.com/entry/165

 

/database/factories/UserFactory.php

・・・

$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

こんな風になっている。

 

シーダでシーダファイルを作成する

$ docker-compose exec php-fpm php artisan make:seeder UsersTableSeeder

 

 

/database/seeds/UsersTableSeeder.php

<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\User::class, 100)->create();
    }
}

 

 

/database/seeds/DatabaseSeeder.php

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UsersTableSeeder::class);
    }
}

 

サンプルのレコードをシーディングします。

$ docker-compose exec php-fpm composer dump-autoload
$ docker-compose exec php-fpm php artisan db:seed

 

QueryBuilderでの実装のUserQBRepositoryクラス, Eloquentでの実装でのUserEQRepositoryで実装先を2つ作る。

app
│──Repositories
│     ┗─User
│         ┗─UserRepositoryInterface
│         ┗─UserQBRepository
│         ┗─UserEQRepository
│──Models
│     ┗─
│--User.php

 

 

/Repositories/User/UserRepositoryInterface.php

<?php

namespace App\Repositories\User;


interface UserRepositoryInterface
{
    public function LastUser();
}

 

QueryBuildを利用する場合、Eloquentを利用する場合で実装先を2つ作ります。これをメソッドインジェクションを利用して切り替えることができるようにします。

 

 

/Repositories/User/UserQBRepository.php

<?php

namespace App\Repositories\User;
use DB;

class UserQBRepository implements UserRepositoryInterface
{
  protected $table = 'users';

  public function LastUser()
  {
      return DB::table($this->table)->where('id', DB::raw("(SELECT MAX(id) FROM users)"))->first();
  }
}

 

/Repositories/User/UserEQRepository.php

<?php

namespace App\Repositories\User;
use App\User;

class UserEQRepository implements UserRepositoryInterface
{
    protected $table = 'users';

    public function LastUser()
    {
        return User::whereRaw('id = (SELECT MAX(id) FROM users)')->get();
    }
}

 

 

サービスプロバイダの作成

$ docker-compose exec php-fpm php artisan make:provider RepositoryServiceProvider

 

/Providers/RepositoryServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(
            \App\Repositories\User\UserRepositoryInterface::class,
            \App\Repositories\User\UserQBRepository::class,
            //\App\Repositories\User\UserEQRepository::class,
        );
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

 

 

/config/app.php

    'providers' => [

・・・

+        App\Providers\RepositoryServiceProvider::class,

 

コントローラの作成

$ docker-compose exec php-fpm php artisan make:controller UserController

 

/app/Http/Controller/UserController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use \App\Repositories\User\UserRepositoryInterface AS UserRepository;

class UserController extends Controller
{
    protected $User;

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

    public function index()
    {
        $data = $this->User->LastUser();

        $result = [
            'className' => get_class($this->User),
            'userName'  => $data->name
        ];
        var_dump($result);
    }
}

index()の引数にインターフェイスを指定することで、メソッドインジェクションを行う。

 

実装の切り替え

 

実装先を入れ替えることで切り替えることができる

    public function register()
    {
        $this->app->bind(
            \App\Repositories\User\UserRepositoryInterface::class,
            \App\Repositories\User\UserQBRepository::class,
            //\App\Repositories\User\UserEQRepository::class,
        );
    }
    public function register()
    {
        $this->app->bind(
            \App\Repositories\User\UserRepositoryInterface::class,
            //\App\Repositories\User\UserQBRepository::class,
            \App\Repositories\User\UserEQRepository::class,
        );
    }

 

 

トランザクションの位置とリポジトリパターンでの抽象化

Laravel try catchとtransactionの位置

 

@see

 

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)