そのController重すぎない？

Laravel学習仕立ての最初の方ってついついなんでもControllerに詰め込みすぎちゃうよね、、、。
商品一覧を管理者側で作成や編集したりするコード見返してたけどこんな感じだった。

```php:laravel/app/Http/Controllers/Admin/ItemController.php
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Item;
class ItemController extends Controller {
	public function index() {
		$items = Item::get();
		return view('admin.index', compact('items'));
	}
	public function detail($id) {
		$item = Item::find($id);
		return view('admin.detail', compact('item'));
	}
	public function add() {
		return view('admin.add');
	}
	public function create(Request $request) {
		$request->validate([
			'item_name' => 'required|max:255',
			'explanation' => 'required',
			'price' => 'required|integer|digits_between:2, 7',
			'stock' => 'required|integer|digits_between:1, 5',
		]);
		$item = new Item;
		$item->item_name = $request->item_name;
		$item->explanation = $request->explanation;
		$item->price = $request->price;
		$item->stock = $request->stock;
		$item->save();
		return redirect(route('admin.index'))->with('flash_message', '商品が追加されました');
	}
	public function edit($id) {
		$item = Item::find($id);
		return view('admin.edit', compact('item'));
	}
	public function update(Request $request, $id) {
		$item = Item::find($id);
		$request->validate([
			'item_name' => 'required|max:255',
			'explanation' => 'required',
			'stock' => 'required|integer|digits_between:1, 5',
		]);
		$item->item_name = $request->item_name;
		$item->explanation = $request->explanation;
		$item->stock = $request->stock;
		$item->save();
		return redirect(route('admin.detail', $id))->with('flash_message', '商品詳細が変更されました');
	}
}
```
追加・更新処理はControllerでやってもいいんだけど、バリデーションぐらいは別のところで行いたいよね
そんな時はFormRequestを使おう！
まずはtopに行って

```
$ php artisan make:request ItemRequest
```
これでlaravel/app/Http/Requestsの下にItemRequest.phpが作成される

```php:laravel/app/Http/Requests/ItemRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\Request;
use App\Item;

class ItemRequest extends FormRequest {
	/**
	 * Determine if the user is authorized to make this request.
	 *
	 * @return bool
	 */
	public function authorize() {
		return true; //変更
	}

	/**
	 * Get the validation rules that apply to the request.
	 *
	 * @return array
	 */
	public function rules() {
		$item = Item::find($this->id);
		return [
			// バリデーションをここへ移動
			'item_name' => 'required|max:255|unique:items,item_name,' . $item->item_name . ',item_name', //同じIDの名前は重複して良い（変更無しでもバリデーションをかけない）
			'explanation' => 'required',
			'price' => 'sometimes|required|integer|digits_between:2, 7', //編集時にもバリデーションがかかってしまうためsometimesを追加
			'stock' => 'required|integer|digits_between:1, 5',
		];
	}
}
```

```php:laravel/app/Http/Controllers/Admin/ItemController.php
<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Requests\ItemRequest; //追加
use App\Http\Controllers\Controller;
use App\Item;

class ItemController extends Controller {
	public function create(ItemRequest $request) { //RequestをItemRequestに変更
		//処理
	}
	public function update(ItemRequest $request, $id) { //createと同様
		//処理
	}
}
```
これでバリデーションは完璧！

追加・更新処理の部分も少なくしたい時にどうするか。
これは処理をそのままモデルに移してtrueを返す。（条件分岐するならfalseも使う)

```php:laravel/app/Item.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Item extends Model {
	protected $fillable = ['item_name', 'explanation', 'price', 'stock'];
	public function addDb($request) {
		$item = new Item;
		$item->item_name = $request->item_name;
		$item->explanation = $request->explanation;
		$item->price = $request->price;
		$item->stock = $request->stock;
		$item->save();
		return true;
	}
	public function editDb($request) {
		$item = $this->find($request->id);
		$item->item_name = $request->item_name;
		$item->explanation = $request->explanation;
		$item->stock = $request->stock;
		$item->save();
		return true;
	}
}

```

そしてコントローラーから移した処理の関数を呼び出す。

```php:laravel/app/Http/Controllers/Admin/ItemController.php
<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Requests\ItemRequest;
use App\Http\Controllers\Controller;
use App\Item;

class ItemController extends Controller {
	public function index() {
		$items = Item::get();
		return view('admin.item.index', compact('items'));
	}
	public function detail($id) {
		$item = Item::find($id);
		if ($item) {
			return view('admin.item.detail', compact('item'));
		} else {
			set_message('該当する項目が見当たりません', false);
			return redirect(route('admin.item.index'));
		}
	}
	public function add() {
		return view('admin.item.add');
	}
	public function create(ItemRequest $request) {
		(new Item)->addDb($request);
		return redirect(route('admin.item.index'))->with('flash_message', '商品が追加されました');
	}
	public function edit($id) {
		$item = Item::find($id);
		if ($item) {
			return view('admin.item.edit', compact('item'));
		} else {
			set_message('該当する項目が見当たりません', false);
			return redirect(route('admin.item.index'));
		}
	}
	public function update(ItemRequest $request, $id) {
		(new Item)->editDb($request);
		return redirect(route('admin.item.detail', $id))->with('flash_message', '商品詳細が変更されました');
	}
}

```
これでスッキリかけました！