route()・action()はどちらもURLを作成するときにすごく便利です。
route('sample.index'); //こちらは、routes/web.phpでnameを指定する必要があります。
action('SampleController@index');
どちらも同様のURLを作成してくれます。第二引数で、パラメータを渡すことができます。
Bladeのほうで、利用するときは、旧型の書き方と比べると可読性が全然違います。
###旧型
{{Form::open(['url' => 'http://sample/index?id='. $data['id']. '&name='. $data['name'])}}
###route()・action()利用時
url属性を使用した場合
{{Form::open(['url' => route('sample.index', [$data])])}}
{{Form::open(['url' => action('SampleController@index', [$data])])}}
LaravelのBladeには、routeとactionの属性が用意されています(パラメータがない場合は利用する)
(こちらの形でも、input hiddenを使えば、パラメータを渡すことは可能ですが、個人的には、すべてurl属性を使って統一するほうが見やすい気がします。)
{{Form::open(['route' => 'sample.index'])}}
{{Form::open(['action' => 'SampleController@index])}}
##Formにroute関数を使用して、特定の場合、思った挙動をしなくなる話
当然と言われれば、それまでの話なのですが、URLにidを埋め込んで、そのidに、/を入れたときに、思った通りの挙動をしません。例をあげてみます。
Route::get('/test/{id}/index', 'TestController@index')->name('test.index');
idごとのデータのindexメソッドの処理がはしる想定のルートです。
public function index(Request $request, $id)
{
dd($id);
}
引数で、idを受け取ります。それでは、bladeを編集します。
{{Form::open(['url' => route('test.index', ['id' => '1']), 'method' => 'get'])}}
{{Form::submit('送信')}}
{{Form::close()}}
まずは、idに1をいれて、ボタンを押下してみます。
![Screenshot_8.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F325600%2F42d9af4f-f0f4-a2e9-c4f0-7e5aeb241ee8.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=4bc170c123389c2f40be61d44434ec8d)
想定通り、1が表示されました。それでは、/をいれてみます。
{{Form::open(['url' => route('test.index', ['id' => '/']), 'method' => 'get'])}}
{{Form::submit('送信')}}
{{Form::close()}}
/を入れて試してみます。404エラーがでました。URLをみると、///となっており、URLがおかしくなっています。
![Screenshot_10.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F325600%2Fb0da7f1e-814a-19ff-5a9a-33ca7003868a.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=f222d7c6fa314f21478f7f45672e1222)
###対処法
本来、/はURLの区切り、?はパラメータを渡すときにURLの大切な役を担っています。それを、URLのパラメータとして使用するためには、エンコードする必要があります。
Route::get('/test/{id}/index', 'TestController@index')->name('test.index')->where('id', '(.*)');
![Screenshot_11.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F325600%2F794ccf34-1edb-6887-877b-b7a3f157faaa.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=30d9ed45484cd789aa39411c629007e2)
できました。?をパラメータに使いたい場合は、エンコードされていたらそのまま使えますが、されていなかったら、urlencode('?')などでエンコードしてから、パラメータとして使用しましょう。
##まとめ
パラメータに/や?を使わないようするのが一番いいと思います