プログラマというのは、その性質上、いかにプログラムの行数を少なくして、やりたいことをクリーンに明確に表現できるかに時間を費やしたりします。そして、重複の表現はすぐに気づき、忌み嫌い、どうしたらそれをなくすことができることを日夜考えます。
私もそのひとりで、例えば、昔以下のようなコードありました、「どうにかならんかな?」と気になっていました。
.. // 会員登録 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行になったけれど、コントローラはちょっとわかりにくいかな、とも思いますね。
メルマガ購読の申し込みはこちらから。