You are here

Route::match

プログラマというのは、その性質上、いかにプログラムの行数を少なくして、やりたいことをクリーンに明確に表現できるかに時間を費やしたりします。そして、重複の表現はすぐに気づき、忌み嫌い、どうしたらそれをなくすことができることを日夜考えます。

私もそのひとりで、例えば、昔以下のようなコードありました、「どうにかならんかな?」と気になっていました。

..
// 会員登録     
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行になったけれど、コントローラはちょっとわかりにくいかな、とも思いますね。

Leave a Reply

Top