it-swarm.com.de

Laravel - Wo können Status (Flags) gespeichert werden? Modell, Klasse oder Konfigurationsordner?

Ich muss Status in mt project ausgiebig verwenden. Ich benötige sie für meine users (active, suspended usw.), eine Entität (active, pending_activation, inactive) und für meine Abonnements (active, on_grace_period, not_subscribed, never_subscribed).

Bisher dachte ich, dass der beste Weg ist, sie in der DB zu speichern, aber ich habe das Gefühl, dass es viel einfacher ist, sie in den anderen 3 Optionen zu haben.

Ich dachte auch, dass ich sie in meinem Eloquent Modell als Konstanten speichern kann. Zum Beispiel würde mein Abo-Modell so aussehen:

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

und sie abzurufen, zum Beispiel in einer Blade-Ansicht:

// 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

Wie wäre es, wenn Sie dasselbe tun, aber den Ordner config verwenden und eine Datei mit dem Namen status.php hinzufügen. Der Zugriff in der Ansicht würde folgendermaßen aussehen:

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

Gibt es einen besseren Weg?

Wie steht es auch mit dem anderen Teil der Gleichung, dh dem Status, der in der DB gespeichert ist? Sollte ich nur eine status-Spalte für die Abonnementtabelle haben und speichern, was die App vorschreibt, oder sogar eine separate Tabelle erstellen, subscription_statuses und einen foreign_keysubscription_status_id in der subscriptions-Tabelle haben?

15
Cristian

Ich neige dazu, ein bestimmtes Modell für Status zu erstellen, das als Aufzählung dient. Wenn ich also ein Event Modell habe, kann es sein, dass ich ein entsprechendes EventStatus Modell habe, das so aussieht:

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

Ich kann dann so prüfen:

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

Normalerweise füge ich meinen Modellen auch praktische Methoden hinzu:

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

Für die "menschenfreundlichen" Zeichenfolgen habe ich dann eine Sprachdatei mit den folgenden Textzeichenfolgen:

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

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

Ich bin mit den anderen Antworten nicht einverstanden. Ihre Statusinformationen sollten in der Datenbank gespeichert werden. Eine gut gestaltete Datenbank sollte klar und ohne die Anwendung verwendbar sein. Was passiert, wenn Sie sich entscheiden, diese Datenbank auch für eine mobile Anwendung zu verwenden? Sie werden einen Teil der Informationen aus der Datenbank entfernen und nur in Laravel speichern. Dies bedeutet, dass Sie diese Statusliste auch in Ihrer Mobilanwendung duplizieren und auf beiden Seiten verwalten müssen.

Diese Art von Informationen sollte in der Datenbank gespeichert werden.

Option 1

Wenn Ihre Benutzer immer nur einen Status haben können, sollten Sie ein enum-Feld mit den Werten subscribed, subscribed-grace, not-subscribed, never-subscribed verwenden.

Dies ist aus Ihrer Sicht genauso einfach:

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

Option 2

Wenn Sie jedoch möglicherweise mehrere Status haben, sollten Sie mit ziemlicher Sicherheit ein separates Feld für jeden Status haben und eine TINYINT verwenden, um einen 1 oder 0 zu speichern.

Separate Statustabelle?

Ich kann keinen guten Grund dafür finden, eine separate Statustabelle zu verwenden, es sei denn, Sie erwarten, dass Sie möglicherweise viel mehr Status hinzufügen, und selbst wenn Sie mehr hinzufügen, können Sie der enum einfach neue Werte hinzufügen oder ein neues Feld hinzufügen, je nachdem, welche Option passt .

Eine Statustabelle ist ideal, wenn Sie neben Benutzern die Status für viele andere Tabellen in der Datenbank verwenden möchten.

Der einzige andere Grund für eine separate Statustabelle wäre, wenn Sie die Bedeutung eines bestimmten Status ändern möchten. Dies würde bedeuten, dass Sie den Status in der Statustabelle umbenennen könnten, die Benutzer jedoch weiterhin über den Primärschlüssel mit ihm verbunden wären. Das Ändern der Bedeutung eines Status mit den vorherigen beiden Methoden würde Änderungen an der Struktur mit sich bringen.

Es kommt wirklich darauf an, wie Sie davon ausgehen, dass Sie sie verwenden werden, aber es gibt keinen Grund, sie nicht in der Datenbank zu belassen.

6
AJReading

In meinen Anwendungen arbeite ich ähnlich wie bei @Martin Bean, außer dass ich keine separaten Klassen für den Status erstelle, sondern diese in der vorhandenen Klasse/dem Modell speichere.

Ich werde user, subscription und entity eine Entität nennen.

  • Entität haben eine status, die in ihrem Modell und ihrer Tabelle in der Datenbank vorhanden ist.
  • Jedes Modell hat Konstanten möglicher Werte für status wie ACTIVE, INACTIVE, PENDING usw., und diese können für jedes Modell variieren.
  • Erstellen Sie Methoden für den Umgang damit wie getStatusLabel(), listStatus(), isActive(), isX() usw.
  • Diese isActive/X() werden nur erstellt, wenn dies wirklich erforderlich ist. Möglicherweise hat ein Modell den Status 4, Sie führen jedoch nur Vergleiche mit einem bestimmten Modell durch. Daher würde ich nur eine isX() für diesen Status erstellen.

Beispiel

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;
    }
}

Jede Methode hat Vor- und Nachteile. Es ist gut, sich dessen bewusst zu sein.

Tabelle - Vor- und Nachteile (Methode von AJReading):

  • Hinzufügen und Verwalten einer Tabelle scheint mühsam
  • Nur eine andere Tabelle und ein anderes Modell können dazu führen, dass sich unser Code überladener anfühlt (nicht zu sagen, dass dies ein guter Grund ist, nicht nur zu sagen, dass es irgendwie wahr ist).
  • Es wird unangenehm, wenn wir eine Anwendungslogik haben, die von etwas in der Datenbank abhängig ist (Dinge in der Datenbank fühlen sich so an, als ob sie variabel sein sollten, wenn wir die Anwendungslogik darauf aufbauen, werden sie benötigt).
  • Jetzt haben wir Migrationen, aber davor waren diese der Fluch der Existenz von Entwicklern (sie machten das Wechseln zwischen Servern zu einer schrecklichen Aufgabe, weil Sie daran denken mussten, neue Status hinzuzufügen, oder Ihre App stürzte ab) ... hätten Sie müssen Tun Sie dies bei jeder Datenbankänderung, aber dies waren immer noch diejenigen, die ich am häufigsten tun musste
  • Gut für die Datenintegrität

Konstanten verwenden : Vor-/Nachteile (Martin Beans Methode):

  • Vermeidet die oben genannten Nachteile
  • Diese sind in Ihrem Code und Ihrer Basislogik leicht zu referenzieren
  • Sie müssen nicht einmal ein neues Modell oder eine neue Tabelle erstellen (das tut er in seinem Beispiel, aber Sie können sie auch einfach in das Ereignismodell einfügen).
  • Sie eignen sich hervorragend für Werte, die NUR hinter den Kulissen verwendet werden
  • Sie reduzieren die Anzahl der Abfragen
  • Sie fühlen sich einfach nicht so arbeitsintensiv. Sie scheinen sich leichter umgestalten zu lassen.
  • Con: Sie werden etwas umständlich, wenn Sie sie kennzeichnen, alle abrufen, Beschreibungen abrufen usw. Die Übersetzungslösung ist gut, aber wenn Sie keine Übersetzungen in Ihrer App verwenden, ist dies auch etwas umständlich.
  • Letztendlich unterbrechen sie den ORM-Fluss, den Sie haben. Wenn alle Ihre anderen Modelle Eloquent erweitern, bricht dies die Form ein wenig.
  • Es gibt keine wirkliche Einigung darüber, wie dies am besten zu erreichen ist. Viele Leute wenden jedes Mal eine andere Methode an.
  • Wie AJReading sagte, wenn Sie die Datenbank alleine für einen anderen Aspekt des Projekts verwenden müssen, wird es nicht funktionieren

Ich verwende die konstante Methode, aber manchmal würde ich meinen, mein Code könnte sauberer und einfacher sein, wenn ich Tabellen verwendet hätte. Es ist ein harter Anruf. Ich möchte, dass es eine gut dokumentierte Lösung für die konstante Methode gibt, um zumindest Konsistenz zu schaffen, aber ich habe noch keine gesehen. So oder so glaube ich nicht, dass es eine richtige oder falsche Antwort gibt. Wählen Sie eine und machen Sie mit!

1
Sabrina Leggett

Fragen Sie sich bei Entscheidungen dieser Art:

"Wird es jemals eine Instanz meiner Anwendung geben, in der es Sinn macht, dass diese Konstanten unterschiedliche Werte haben?"

z.B. eine Testumgebung, eine Art Klon, eine noch nicht definierte, aber mögliche zukünftige Version ...

Wenn die Antwort auf diese Frage "Ja" ist, sollte es wahrscheinlich in der Anwendungskonfiguration gehen.

Wenn es unwahrscheinlich (oder dumm) ist, dass sich die Werte ändern, gehören sie zum Modell und sollten in das Modell aufgenommen werden.

Ich schlage vor, dass es in diesem Fall keinen vernünftigen Grund gibt, jemals eine Version der Anwendung mit unterschiedlichen Werten zu haben, also würde ich sie in das Modell aufnehmen.

0
DanSingerman