Laravel6を使って感じた自分なりのベストプラクティス

# はじめに
「PhpStorm&Dockerで最強のLaravel開発環境を作ろう！」ってタイトルで投稿するつもりが、最強どころか最弱って言われそうな内容だったため、内容を変えて投稿します。

Laravel6を使って予約システムの開発を2ヵ月程度やっているのですが、自分なりにこれはこうやったほうがいいってことがありました。
Laravelでちゃんとした？システムを一から作ったのが初めてでしたので、当たり前のことだったり間違っていることも多々あるかと思いますがよろしくお願いします。
環境は、下記の通りです。

|Name|Version|
|---|---|
|PhpStorm|2019.3|
|php|7.2.25|
|Laravel|6.4.1|
|MySQL| 5.7.28|

# リクエストパラメータはスネークで
うっかりキャメルで作っちゃったら、fillの恩恵を受けにくくなります。
テーブルのカラム名に合わせてスネークで宣言しましょう。

```php:Itemcontoller.php
$data = $request->validated();
app(Item::class)->fill($data)->save();
```

```html:create.blade.php
<input type="text" name="hoge_fuga_name" >
<input type="checkbox" name="hoge_fuga_type[]" >
```

# リレーションもスネークで、ビュー変数は配列形式で！
ビューに出力する時に、キャメルにしてるとキャメルとスネークが混在してなんか嫌な気分になります。
僕はビュー内で、エンティティ（例だと\$reservation）を出力する時、アロー演算子と配列形式が使えますが、使い分けするのがしんどいのでオール配列形式のほうが好きです。(\$reservation->hoge_details ではなく\$reservation['hoge_details'])

```php:App\HogeReservation.php
namespace App;
..
Class class HogeReservation extends Model
{
    ...
    public static options = [
       1 => ['name' => 'A'],
       2 => ['name' => 'B'],
       3 => ['name' => 'C'],
    ];
    public function hoge_details()
    {
        return $this->hasMany(HogeReservationDetail::class);
    }
    public function hoge_item()
    {
        return $this->belongsTo(HogeItem::class);
    }
```

```html:index.blade.phpスネークだと
<p>item: {{ $hoge_reservation['hoge_item']['name'] }}</p>
<p>option: {{ $hoge_reservation['options'][1]['name'] }}</p>
@foreach($hoge_reservation['hoge_details'] as $detail)
<table>
<tr>
<td>{{ $detail['name'] }}</td>
</tr>
</table>
@endforeach
```
うん普通

```html:index.blade.phpキャメル＆アロー演算子にすると
<p>item: {{ $hoge_reservation->hoge_item->name }}</p>
{# ここは配列で指定しないとエラーになる #}
<p>option: {{ $hoge_reservation['options'][1]['name'] }}</p> 
@foreach($hoge_reservation->hogeDetails as $detail)
<table>
<tr>
<td>{{ $detail->name }}</td>
</tr>
</table>
@endforeach
```
思ったより大丈夫だけど、アロー演算子と配列とスネークとキャメルが混ざるとなんか分かりにくい。。

# テーブルもフィールドもリクエストもメソッドもなるべく区切らなくてもいいよう命名する
これが鉄則です。上記の理由でいろいろ迷わなくて済むので。

# resource/lang/*/validation.phpの:attribute〇〇はすべて消そう
バリデーションエラーの内容ですが、標準ではすべてattributeが入っています。

```:php
   'email'                => ':attributeには有効なメールアドレスを指定してください。',
// ではなく
   'email'                => '有効なメールアドレスを指定してください。',
```
Laravelではbootstrap4が標準で読み込まれておりますので、メールアドレスの入力欄はこんな感じになるかと思います。

```html:edit.blade.php
<dl>
<dt class="col-md-3"><label for="input-email">メールアドレス</label></dt>
<dd class="col-md-9">
    <div class="input-group">
        <input type="text" class="form-control @error('email') is-invalid @enderror"
               id="input-email" name="email" value="{{old('email',$item['email'])}}"
        @error('email')
        <div class="invalid-feedback">{{$message}}</div>
        @enderror
    </div>
</dd>
</dl>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68254/eae1bc2d-6892-3203-f6fc-0a6b4317a72a.png)

:attributeは表示の幅を取るし、しつこいので、削除しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68254/dc0b1776-5b78-5367-363f-de413347100b.png)

# ``<script type="module"`` でjqueryを使おう
Viewで独自のJavaScriptを読み込めるようlayoutに``@yield('script')``を設定するかと思います。

```html:views/layouts/front.blade.php
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
@yield('script')
..
```
laravel6は標準でnpm経由で読み込まれているbootstrapはjqueryも一緒に読み込まれているので、わざわざjqueryを読み込まなくても``<script type="module">``でjqueryが使えます！

```html:views/item/input.blade.php
@extends('layouts.front')
@section('script')
    <script type="module">
        $('#input-email').on('click',function(){
            ...
        });        
    </script>
@endsection
@section('content')
...
```

# おわりに
手抜きになってしまいすいません。。