web-dev-qa-db-ja.com

Laravel-ブレードでビューをレンダリングするための多くのアクセサ(ミューテータ)

Laravel 7プロジェクトがあり、表示する前にモデルからビューへの大量のデータ変換が必要です。

Laravel Accessors を使用することを考え、ブレード.phpファイルで直接使用しました。
しかし、単純なhtmlテーブルの処理が終了したとき、コードを調べたところ、アクセサが多すぎ、名前の一部が読みにくいと思いました。

ブレードビュー

@foreach($races as $race)
<tr>
    <td>{{ $race->display_dates }}</td>
    <td>{{ $race->display_name }}</td>
    <td>{{ $race->type->name }}</td>
    <td>{{ $race->display_price }}</td>
    <td>{{ $race->display_places }}</td>
    <td>{{ $race->online_registration_is_open ? 'Yes' : 'No' }}</td>
</tr>
@endforeach

コントローラ

public function show(Group $group)
{
    $races = $group->races;
    $races->loadMissing('type'); // Eager loading
    return view('races', compact('races'));
}

型番

// Accessors
public function getOnlineRegistrationIsOpenAttribute()
{
    if (!$this->online_registration_ends_at && !$this->online_registration_starts_at) return false;
    if ($this->online_registration_ends_at < now()) return false;
    if ($this->online_registration_starts_at > now()) return false;
    return true;
}

public function getNumberOfParticipantsAttribute()
{
    return $this->in_team === true
        ? $this->teams()->count()
        : $this->participants()->count();
}

// Accessors mainly used for displaying purpose
public function getDisplayPlacesAttribute()
{
    if ($this->online_registration_ends_at < now()) {
        return "Closed registration";
    }
    if ($this->online_registration_starts_at > now()) {
        return "Opening date: " . $this->online_registration_starts_at;
    }
    return "$this->number_of_participants / $this->max_participants";
}

public function getDisplayPriceAttribute()
{
    $text = $this->online_registration_price / 100;
    $text .= " €";
    return $text;
}

public function getDisplayDatesAttribute()
{
    $text = $this->starts_at->toDateString();
    if ($this->ends_at) { $text .= " - " . $this->ends_at->toDateString(); }
    return $text;
}

public function getDisplayNameAttribute()
{
    $text = $this->name;
    if ($this->length) { $text .= " $this->length m"; }
    if ($this->elevation) { $text .= " ($this->elevation m)"; }
    return $text;
}

このコードは機能していますが、多くの短所があると思います。たとえば、ここでnameアクセサを作成しているときに、関連付けられたDBテーブルにgetDisplayNameAttribute列がある場合など、読みやすさ、間違いの可能性があります。
そして、それはほんの始まりに過ぎません。他のビューに30〜40個多くのアクセサが必要になると思います...また、それらのいくつかを何度も使用する必要があります。たとえば、getDisplayNameAttribute通常のページと管理ページ(そしておそらくそれ以上)で使用されます。

JsonResourceViewComposer も調べましたが、JsonResourceAPIsのようであり、ViewComposerは特にViews

また、既存のdb列との間違いを減らすために、acc_のようなものをアクセサーの前に付けることも考えました。

public function getAccDisplayNameAttribute() { ... };

しかし、私はそれが解決策だとは本当に思っていません。私がしていることが正しいか間違っているかさえわかりません。また、インターネットを介してベストプラクティスを検索しましたが、成功しませんでした。

6
Alice

Accessorsおよびmutatorsは、Laravelの通常のゲッターおよびセッター関数です。それはそれを言うためのより「エレガントな」方法にすぎません。

ゲッター関数とセッター関数は、クラス内の変数をより適切に制御できるようにするためのものだと言えるかもしれませんが、少し理解するのには役立ちません。

それは何のためですか?なぜそれを使うのですか?

私たちはすでにDRYの原則(自分自身を繰り返さないでください)に精通しています。これは、重複は排除すべき論理であると述べています。またはキッチン言語で;理由もなく時間がかかるため、同じコードを2回記述しないでください。

それで、これはどのように役立ちますか?

たとえば、サーバー上の別のアプリ(hunspellなど)を使用しているスペルチェッカークラスがあります。小さな文字列の場合、それを直接使用でき、リクエストが来たら、Shell_execを使用してコマンドを呼び出してリクエストを処理し、結果を取得してそれを返します-全員が満足しています。

ただし、テキストが長すぎると、phpが30秒(デフォルト)の制限を超えてしまい、結果が得られません。その場合、デーモンプロセスによって実行されるスクリプトを作成できるため、30秒の制限は問題になりません。リクエストが届くと、たとえばunixソケットを使用してテキストをデーモンプロセスに渡し、バックグラウンドプロセスがスペルチェックを実行して結果を返します。

どちらの場合も、スペルチェッククラスに特定の変数を設定する必要があります。検証またはフォーマットが必要になる場合があります。また、時間をかけて混乱させ、何かをめちゃくちゃにできる可能性のある場所を増やすので、2度開発したくありません。

データを設定または取得するために準備を使用する必要がある場所が2つ以上ある場合もあり、2つの場所だけでもコードの重複を回避するのに非常に役立ちます。これは、コードの複雑化を防ぐのにも役立ちます。

これだけではありません!

時々あなたはクラスを書いて、神はそれを誰が使うか知っています。たぶんそれは公開パッケージ用です。その後、開発者はパッケージを取得したときに、電子メールがどのように検証されるかについて気になりたくありません。彼は、ファイルから変数を取得する前に、特定の変数の文字列の末尾から\nを削除する必要がある理由を知りたくありません。彼は整数検証の実装部分を気にしたくありません。彼はパッケージを使用して、できるだけ早く仕事を終わらせたいと思っています。

セッターとゲッターを使用して行うことは、これらのメソッドを介してクラス変数を制御することによってクラス変数を保護することに他なりません。

場合によっては、クラス内の変数を非表示にして、他のクラスがそれらに依存しないようにする必要があります。これにより、実装と変数の型を柔軟に変更できます。

あなたはいつもそれらを使うべきですか?

いいえ。関数呼び出しがphpで遅い。ネイティブLaravelコードと比較してPHPがどれだけ遅いかを確認してください。ゲッターとセッターを書くことはまったく意味がなく、時間の浪費になることもあります。

いつそれを使うべきですか?

変数へのアクセスを制限する必要がある場合に使用します。各フィールドのゲッターとセッターを作るのはやり過ぎです。実際の状況によって異なりますので、必要な場所でのみご利用ください。

このトピックの詳細

ゲッターとセッター?

getterとsetter/accessorsを使用する理由

https://dev.to/scottshipp/avoid-getters-and-setters-whenever-possible-c8m

0
David Hlavati