web-dev-qa-db-ja.com

Laravel-ステータス(フラグ)を保存する場所?モデル、クラス、または構成フォルダ?

Mtプロジェクトでステータスを広範囲に使用する必要があります。私は、usersactivesuspendedなど)、エンティティ(activepending_activationinactive)、およびサブスクリプション(activeon_grace_periodnot_subscribednever_subscribed)に必要です。

これまでのところ、それらをDBに格納するのが最善の方法であると考えていましたが、他の3つのオプションに格納する方がはるかに簡単だと感じています。

また、Eloquentモデルに定数として保存できると思いました。たとえば、私のサブスクリプションモデルは次のようになります。

// SubscriptionModel
const SUBSCRIBED_ACTIVE = 1;
const SUBSCRIBED_ON_GRACE_PERIOD = 2;
const NOT_SUBSCRIBED = 3;
const NEVER_SUBSCRIBED = 4;

そしてそれらを、例えばブレードビューで取得します:

// subscription/index.blade.php
@if($user->subscription->status == /App/SubscriptionModel::SUBSCRIBED_ACTIVE)
    <div>You are subscribed. Thank you</div>
@elseif($user->subscription->status == /App/SubscriptionModel::NEVER_SUBSCRIBED)
    <div>You need to create a subscription before being granted full access!</div>
@elseif(...)
    // and so on

同じことをしますが、configフォルダーを使用し、status.phpというファイルを追加します。ビューでそれにアクセスすることは次のようになります:

@if($user->subscription->status == Config::get('status.subscription.SUBSCRIBED_ACTIVE'))
<div>You are subscribed. Thank you</div>
@elseif(...)
// etc

もっと良い方法はありますか?

また、方程式の他の部分、つまりDBに格納されているステータスについてはどうでしょうか。サブスクリプションテーブルのstatus列のみを保持し、アプリの指示を保存するか、別のテーブルsubscription_statusesを作成し、foreign_keysubscription_status_idsubscriptionsテーブルに含める必要がありますか?

21
Cristian

私は、列挙型として機能するステータスの特定のモデルを作成する傾向があります。したがって、Eventモデルがある場合、次のような対応するEventStatusモデルがある可能性があります。

class EventStatus
{
    const CANCELLED = 'EventCancelled';
    const POSTPONED = 'EventPostponed';
    const RESCHEDULED = 'EventRescheduled';
    const SCHEDULED = 'EventScheduled';
}

その後、次のようなチェックを実行できます。

$event->status == EventStatus::CANCELLED;

通常、モデルにも便利なメソッドを追加します。

class Event extends Model
{
    public function isCancelled()
    {
        return $this->status == EventStatus::CANCELLED;
    }
}

「人にやさしい」文字列の場合は、テキスト文字列を含む言語ファイルを用意します。

<?php // resources/lang/en/event_status.php

return [
    EventStatus::CANCELLED => 'Cancelled',
    EventStatus::POSTPONED => 'Postponed',
    EventStatus::RESCHEDULED => 'Rescheduled',
    EventStatus::SCHEDULED => 'Scheduled',
];
18
Martin Bean

他の答えには同意しません。ステータス情報はデータベースに保存する必要があります。適切に設計されたデータベースは、アプリケーションがなくても明確で使用可能である必要があります。このデータベースを使用して、モバイルアプリケーションなどの機能を強化する場合はどうなりますか?データベースから情報の一部を取り出し、それをLaravelにのみ保存します。つまり、ステータスのリストをモバイルアプリケーションにも複製し、2つで維持する必要があります。

この種の情報はデータベースに保存する必要があります。

オプション1

ユーザーがステータスを1つしか持てない場合は、enumフィールドをsubscribedsubscribed-gracenot-subscribednever-subscribedの値で使用する必要があります

これはあなたの見解と同じくらい簡単です:

@if($user->subscription->status == 'subscribed'

オプション2

ただし、複数のステータスがある場合は、ほとんどの場合、ステータスごとに個別のフィールドがあり、TINYINTを使用して1または0を格納する必要があります。

別のステータステーブル?

さらに多くのステータスを追加する可能性があると予想しない限り、別のステータステーブルを使用する十分な理由がわかりません。さらに追加する場合でも、enumに新しい値を追加するか、必要に応じて新しいフィールドを追加できます。どのオプションが適しています。

ステータステーブルは、ユーザー以外のデータベース内の他の多くのテーブルのステータスを使用する場合に最適です。

別のステータステーブルの唯一の他の理由は、特定のステータスの意味を変更することにした場合です。これは、ステータステーブルでステータスの名前を変更できることを意味しますが、ユーザーは引き続きそのプライマリキーを介してステータスにリンクされます。前の2つの方法でステータスの意味を変更すると、構造も変更されます。

実際にそれらをどのように使用するかを予測することによりますが、データベースにそれらを保持しない理由はありません。

6
AJReading

私のアプリケーションでは、@ Martin Beanに似ていますが、ステータスに個別のクラスを作成せず、既存のクラス/モデル内に保存します。

usersubscriptionおよびentity a entityを呼び出します。

  • エンティティモデルとデータベース内のテーブルに存在するstatusがあります。
  • 各モデルには、statusACTIVEINACTIVEなど、PENDINGの可能な値の定数があり、モデルごとに異なる場合があります。
  • getStatusLabel()listStatus()isActive()isX()などのように、それを処理するためのメソッドを作成します。
  • これらのisActive/X()は本当に必要な場合にのみ作成されます。モデルには4つのステータスがありますが、特定の1つに対して比較を行うだけなので、そのステータスに対してisX()を1つだけ作成します。

class User
{
    const STATUS_ACTIVE    = 1;
    const STATUS_SUSPENDED = 2;
    const STATUS_INACTIVE  = 3;

    /**
     * Return list of status codes and labels

     * @return array
     */
    public static function listStatus()
    {
        return [
            self::STATUS_ACTIVE    => 'Active',
            self::STATUS_SUSPENDED => 'Suspended',
            self::STATUS_INACTIVE  => 'Inactive'
        ]
    }

    /**
     * Returns label of actual status

     * @param string
     */
    public function statusLabel()
    {
        $list = self::listStatus();

        // little validation here just in case someone mess things
        // up and there's a ghost status saved in DB
        return isset($list[$this->status]) 
            ? $list[$this->status] 
            : $this->status;
    }

    /**
     * Some actions will happen only if it's active, so I have 
     * this method for making things easier.
     * Other status doesn't have a specific method because
     * I usually don't compare agains them
     * @return Boolean
     */
    public function isActive()
    {
        return $this->status == self::STATUS_ACTIVE;
    }
}

それぞれの方法には長所と短所があります。それぞれに注意することは良いことです。

-長所と短所(AJReadingのメソッド):

  • 面倒なテーブルSEEMSの追加と保守
  • 別のテーブルとモデルを用意するだけで、コードが雑然としているように感じる可能性があります(それが本当だとだけ言って使わないのは良い理由だと言っていない)
  • アプリケーションロジックがデータベース内の何かに依存していると、扱いにくくなります(データベース内のものは、アプリケーションロジックを必要とするものに基づいていると、変数である必要があるように感じます)。
  • 現在は移行がありますが、以前は開発者の存在の悩みの種でした(新しいステータスを追加することを忘れないでください。そうしないとアプリがクラッシュするため、サーバー間の切り替えが大変な作業になります)...データベースを変更してこれを行いますが、それでも私が最も頻繁に行わなければならないものでした
  • データの整合性に優れています

定数の使用:長所/短所(Martin Beanの方法):

  • 上記の欠点を回避
  • これらは、コードや基本ロジックで簡単に参照できます
  • 新しいモデルやテーブルを作成する必要はありません(彼の例では彼が作成していますが、それらをイベントモデルに配置することもできます)。
  • これらは、舞台裏でのみ使用される値に最適です。
  • クエリの量を減らします
  • 彼らは仕事のようには感じません。それらはリファクタリングしやすいようです。
  • 欠点:それらにラベルを付けたり、すべてを取得したり、説明を取得したりすると、彼らはちょっと厄介です。翻訳ソリューションは良いものですが、アプリで翻訳を使用しない場合も、これは少し厄介です。
  • 最終的に、彼らはあなたが行っているORMの流れを壊しています。他のすべてのモデルがEloquentを拡張する場合、これは型を少し壊します。
  • これを最善の方法で行うことについての真の合意はありません。多くの人が毎回異なる方法を使用しています。
  • AJReadingが言ったように、プロジェクトの別の側面でデータベースを単独で使用する必要がある場合は機能しません

私は定数メソッドを使用していますが、テーブルを使用した場合、コードがよりクリーンでシンプルになると思うことがあります。それは難しいコールです。少なくとも一貫性を作成するための定数メソッドの十分に文書化されたソリューションがありたいのですが、まだ確認していません。どちらにしても、正しい答えと間違った答えがあるとは思いません。一つ選んで、一緒に行きましょう!

1
Sabrina Leggett

この性質の決定については、次のことを自問してください。

「これらの定数が異なる値を持つことが理にかなっている私のアプリケーションのインスタンスはありますか?」

例えばテスト環境、ある種のクローン、まだ定義されていないが将来のバージョンの可能性...

その質問への答えが「はい」である場合、それはおそらくアプリケーション構成に入るはずです。

値が変更される可能性が低い場合(またはだまされている場合)は、値が属しているため、モデルに含める必要があります。

この場合、異なる値のアプリケーションのバージョンが存在することには合理的な理由はないので、モデルに入れます。

0
DanSingerman