作ったもの
LaravelのCRUDコード&Testコードをmigrationの項目から自動生成できるツールです。
【URL】
https://7k095m9l6q.csb.app/
以下の構成のコードが作れます。(具体的な内容は後で紹介)
- Controller
- Service
- TestCase
▼おまけのコード
- Vue.jsのsample
- bladeのsample
- Routing (API)のsample
利用シーン/メリット
- CRUD処理の実装が簡単になる
- Serviceクラスに実処理を書いてControllerを肥大化させないようにする
- 自動生成なのでタイプミスによるバグがなくなる
- UnitTestをして正しく動くことを確認できる
- インストール不要、ブラウザからいつでも利用可能 (無料)
実際利用してから新規機能の開発効率が5倍くらい上がりました。
なぜ作ったのか
**「早く、動くモノを作る」**ためにどうしたらいいのかを考えた。
DB設計して、基本的なCRUDができるようになるための実装はルーティン作業だと気づいた。
【これまでの実装フロー】
①DB設計
↓
②migration作成
↓
③Modelクラス実装
↓
④Controller実装(create, get, update, delete..) ★
↓
⑤Service実装(create, get, update, delete..) ★
↓
⑥フロント実装(js, bladeなど)
↓
⑦テスト:データの取得→表示、新規作成や更新ができることを確認
↓
⑧バグを修正して仕上げる
一通り実装してからテストをすると、大抵どこかタイプミスがあったり、引数が間違っていたり、記述ミスがあったりしてエラーで動かないことが多い。
でもやろうとしていることは単純な処理なので、ここに時間を費やしてしまうのは時間のムダである。
データの項目名/型が違うだけで、あとは基本全て同じ動き(=実装)になる。
機械的に決まるコード(考えなくてもいいコード)なら自動化してしまえ!ということで、本ツールを作った。
どうやって作ったか
以下のFWと環境でオンライン上で完結させた。
FW : Vuetify.js
環境: codesandbox
ロジックは文字の連結だけで済むのでjsが動けばよかった。
スタイルの調整とかも面倒なので、マテリアルデザインが内包されたVueのフレームワークである「Vuetify.js」を使ってみた。
開発期間
12時間くらいで完成(週末の合間に実装)
使い方
使い方はめちゃくちゃ簡単です。
- Model名を入力
- updateのキーを入力
- selectのキーを入力
4-1. カラムを入力
カラムは一個ずる入れるのは面倒ですよね。
migrationがすでにできてるから、そこから一発でバチン!と一括入力することもできます。
(3) CHECKボタンをクリック
id(increments)とtimestampsを除外して読み取ります
生成されるコード
Controller
以下のコードができるので、COPYボタンでコピーしてControllerに貼り付けます
private $postService;
public function __construct(PostService $postService)
{
$this->postService = $postService;
$this->middleware('auth');
}
public function createPost()
{
$this->middleware('auth');
// $user_id = Auth::user()->id; // if you need login userId
$user_id = request('userId');
$title = request('title');
$body = request('body');
$this->postService->createPost($user_id, $title, $body);
return ['code' => '200']; // TODO
}
public function updatePost()
{
$this->middleware('auth');
// $user_id = Auth::user()->id; // if you need login userId
$id = request('id');
$user_id = request('userId');
$title = request('title');
$body = request('body');
$this->postService->updatePost($id, $user_id, $title, $body);
return ['code' => '200']; // TODO
}
public function getPost($userId)
{
$data = $this->postService->getPost($userId);
return ['code' => '200', 'data' => $data]; // TODO
}
Service
同様にServiceクラスにコピペしましょう
public function createPost($user_id, $title, $body)
{
$model = new Post();
$model->user_id = $user_id;
$model->title = $title;
$model->body = $body;
$model->save();
return $model;
}
public function updatePost($id, $user_id, $title, $body)
{
$model = Post::updateOrCreate(
['id' => $id],
['user_id' => $user_id, 'title' => $title, 'body' => $body]);
return $model;
}
public function getPost($user_id)
{
$model = Post::where('user_id', $user_id)->first();
return $model;
}
その他実装点を**Note:**に書いているので忘れずに書きましょう。
TestCase
artisanのmake:test
でテストクラスを作ってそちらにコピペ。
$ php artisan make:test PostTest --unit
private $postService;
public function setUp()
{
$this->postService = new \App\Services\PostService();
parent::setUp();
}
public static function tearDownAfterClass()
{
Post::where('user_id', 99999)->delete();
}
public function testCreatePost()
{
$user_id = 9999; //**おかしなところはちょっと修正してください
$user_id = 10; //**おかしなところはちょっと修正してください
$title = 'This is title';
$body = 'This is body';
$result = $this->postService->createPost($user_id, $title, $body);
$model = Post::where('user_id', $user_id)->first();
$this->assertSame($model->user_id, $user_id);
$this->assertSame($model->title, $title);
$this->assertSame($model->body, $body);
}
public function testGetPost()
{
$user_id = 9999; //**おかしなところはちょっと修正してください
$user_id = 10; //**おかしなところはちょっと修正してください
$title = 'This is title';
$body = 'This is body';
$model = $this->postService->getPost($user_id);
$this->assertSame($model->user_id, $user_id);
$this->assertSame($model->title, $title);
$this->assertSame($model->body, $body);
}
public function testUpdatePost()
{
$id = 9999;
$user_id = 100;
$title = 'This is title[update]';
$body = 'This is body[update]';
$result = $this->postService->updatePost($id, $user_id, $title, $body);
$model = Post::where('user_id', $user_id)->first();
$this->assertSame($model->user_id, $user_id);
$this->assertSame($model->title, $title);
$this->assertSame($model->body, $body);
}
おまけのコード
vue.js
api.php (Routing)
bladeとその他作業メモ
ツール利用後の開発フロー
【これまでの実装フロー】
①DB設計
↓
②migration作成
↓
③Modelクラス作成
↓
④Controller/Service/TestCaseクラス作成
↓
⑤ツールを利用してコードをコピペ ★
↓
⑥テスト(1):Unitテストで動作検証(*ここで正常に動けばServiceクラスはOK) ★
↓
⑦フロント実装(js,bladeなど)
↓
⑧テスト(2):画面からの疎通確認できれば完了
↓
⑨バグを修正して仕上げる(基本バグは出ない)
終わりに
本ツールはあくまで自分の作業を簡単にするために作ったものなので、必ずしも他の人にも便利なものとは限らないです。
クラス設計とか構成がそもそも違うとか、思想が違うとかこだわりがそれぞれあると思うので、もし使えるなら使ってみてくださいというくらいです。
大事なことは「いかに作業時間を減らしつつ、品質を下げず、早くリリースするか」を考えて、自分の作業を簡単にするための外部のツールを導入してみたり、自分で開発してみたり、いろんな工夫をすることがプログラミング業務において重要なことだと思います。
Enjoy!!