
リポジトリパターンのスタイルにするのが勝ちパターンみたいなので覚える。
確かにわかりやすいし、テストしやすくなる。
- テストの切り分け
本来はコントローラのテストだけ、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,
);
}
トランザクションの位置とリポジトリパターンでの抽象化
@see
- LaravelでRepositoryパターンを実装する-入門編-
- PHPUnitのモックで設計とリファクタが捗る
- Laravelにおける後悔しない為のアプリケーション設計
- Laravelリポジトリパターンの実装

