プログラマというのは、その性質上、いかにプログラムの行数を少なくして、やりたいことをクリーンに明確に表現できるかに時間を費やしたりします。そして、重複の表現はすぐに気づき、忌み嫌い、どうしたらそれをなくすことができることを日夜考えます。
私もそのひとりで、例えば、昔以下のようなコードありました、「どうにかならんかな?」と気になっていました。
..
// 会員登録
Route::get ('member/signup', 'MemberController@signup')->name('member.signup');
Route::post('member/signup', 'MemberController@postSignup')->name('member.signup');
..
見ての通り、どちらもメソッド(get, post)は違いますが、URLは同じmember/signupとなります。もちろん、Route::resourceを使うことも可能ですが、URLは、createでなくsignupとしたいし、必要な処理も登録だけです。
上のコードのphp artisan route:listでの出力はこんな感じです。
+--------+----------+-------------------+---------------+---------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+-------------------+---------------+---------------------------------------------------+--------------+ | | GET|HEAD | member/signup | member.signup | App\Http\Controllers\MemberController@signup | web,guest | | | POST | member/signup | member.signup | App\Http\Controllers\MemberController@postSignup | web,guest | +--------+----------+-------------------+---------------+---------------------------------------------------+--------------+
2行も必要でしょうかね?
こう思っているのは私だけではなかったようです。LaravelのマニュアルにRoute::matchを見つけました。
先の2行のルートの指定を以下のように1行にすることができました。
..
// 会員登録
Route::match(['get', 'post'], 'member/signup', 'MemberController@signup')->name('member.signup');
..
php artisan route:listでの出力はこうなりました。
+--------+---------------+-------------------+---------------+---------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+---------------+-------------------+---------------+---------------------------------------------------+--------------+ | | GET|POST|HEAD | member/signup | member.signup | App\Http\Controllers\MemberController@signup | web,guest | +--------+---------------+-------------------+---------------+---------------------------------------------------+--------------+
素晴らしい!と思うとともに、さてどうやって1つのメソッドsignupでGETとPOSTの2つに対応したらよいものか?
解決方法は、
namespace App\Http\Controllers;
use Illuminate\Http\Request
use App\Models\Member;
class MemberController extends Controller {
...
/**
* Signup
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function signup(Request $request)
{
if ($request->method() == 'POST')
{
return $this->postSignup($request);
}
return view('user/member_add');
}
/**
* Save Signup
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postSignup(Request $request)
{
...
}
のように、signupメソッドにおいて、POSTで呼ばれたかを判断して、postSignupをコールします。
しかし、routesは1行になったけれど、コントローラはちょっとわかりにくいかな、とも思いますね。
メルマガ購読の申し込みはこちらから。