Laravel best practices for 2022 ピックアップ

## 概要

[Laravel best practices for 2022](https://benjamincrozat.com/laravel-best-practices)
のController、Eloquent関連をピックアップします(deeplぶち込み翻訳)

### 既存のベストプラティクス

こちらの方が内容も濃い気がするのでまずはこちらを

https://github.com/alexeymezenin/laravel-best-practices/blob/master/japanese.md


### カスタムフォームリクエストを使用する

[カスタムフォームリクエスト](https://readouble.com/laravel/9.x/ja/validation.html#form-request-validation)を使用する主な理由は以下のとおりです。

1. 複数のコントローラでバリデーションを再利用する。
2. 肥大化したコントローラからコードをオフロードする。

カスタムフォームリクエストの作成は、以下のArtisanコマンドを実行することで簡単に行えます。

```php
php artisan make:request StorePostRequest
```
そして、コントローラーで、タイプ・ヒントを出すだけです。

```php
use App\Http\Requests\StorePostRequest;
 
class PostController
{
    function store(StorePostRequest $request)
    {
        $validated = $request->validated();
 
        Post::create($validated);
 
        //
    }
}

```

[カスタムリクエスト](https://readouble.com/laravel/9.x/ja/validation.html#form-request-validation)も認可に使えますが、私は[ポリシー](https://readouble.com/laravel/9.x/ja/authorization.html#creating-policies)に頼る方が好きです。

https://benjamincrozat.com/laravel-best-practices#use-custom-form-requests

### ポリシーの使用
[ポリシー](https://readouble.com/laravel/9.x/ja/authorization.html#creating-policies)が存在する理由はいくつかあります。

- 複数のコントローラで認可ロジックを再利用する。
- 肥大化したコントローラからコードをオフロードする。
- 認可に関連するすべてのものを app/Policies フォルダでチェックアウトすることは、誰にとっても自然なことです。

### シングルアクションコントローラの使用

シングルアクションコントローラの使用
ベストプラクティスに従ったにもかかわらず、コントローラが大きくなりすぎることがあります。

Laravelには、これを解決するための方法があります。シングルアクションコントローラーです。

リソースコントローラのように複数のアクションを含むのではなく、シングルアクションコントローラは1つだけ含みます。

これを作成するには、
```php
php artisan make:controller ShowPostController --invokable
```
コマンドを使用します。

これにより、__invoke という名前のアクションをひとつだけ持つコントローラが作成されます (マジックメソッドの __invoke については[こちら](https://www.php.net/manual/ja/language.oop5.magic.php#object.invoke)を参照ください)。

そして、Routesの中で、代わりにこのようなことができるようになります。

```diff_php
- use App\Http\Controllers\PostController; 
+ use App\Http\Controllers\ShowPostController; 
 
- Route::get('/posts/{post}', [PostController::class, 'show']); 
+ Route::get('/posts/{post}', ShowPostController::class); 
```

https://benjamincrozat.com/laravel-best-practices#use-single-action-controllers

### イーガーローディングによるN+1問題の防止

N+1問題が発生しないようにするために、リレーションシップをダラダラロードするたびに例外を発生させることができます。
この制限は、あなたのローカル環境のみに適用されるべきです。

```php
Model::preventLazyLoading(
    ! app()->isProduction()
);
```

https://zenn.dev/naoki_oshiumi/articles/85fc131475b8b8

https://benjamincrozat.com/laravel-best-practices#prevent-n1-issues-with-eager-loading


### Eloquentのストリクトモードを使用する

Eloquentのstrictモードは、デバッグにはありがたい。以下のような場合に例外を投げます。

- リレーションシップのレイジーローディング
- 記入不可能な属性の割り当て
- 存在しない(または取得されなかった)アトリビュートにアクセスする場合。

AppServiceProvider.php の boot() メソッドに、次のコードを追加してください。
```php
Model::shouldBeStrict(
    ! app()->isProduction() // Only outside of production.
);
```

https://benjamincrozat.com/laravel-best-practices#use-eloquents-strict-mode


### アクセサとミューテータの新しい宣言方法を使用する
Laravel 9では、[アクセサとミューテータの新しい宣言方法](https://readouble.com/laravel/9.x/ja/eloquent-mutators.html)が導入されました。

現在では、このように宣言する必要があります。
```php
use IlluminateDatabaseEloquentCastsAttribute;
 
class Pokemon
{
    function name() : Attribute
    {
        $locale = app()->getLocale();
 
        return Attribute::make(
            get: fn ($value) => $value[$locale],
            set: fn ($value) => [$locale => $value],
        );
    }
}
```

計算するのに高価な値をキャッシュすることも可能です。

```php

use IlluminateDatabaseEloquentCastsAttribute;
 
function someAttribute() : Attribute
{
    return Attribute::make(
        fn () => /* Do something. */
    )->shouldCache();
}
```


https://benjamincrozat.com/laravel-best-practices#use-the-new-way-of-declaring-accessors-and-mutators


###