J'ai besoin d'utiliser énormément les statuts dans le projet mt. J'en ai besoin pour ma users
(active
, suspended
, etc.), une entité (active
, pending_activation
, inactive
) et pour mes abonnements (active
, on_grace_period
, not_subscribed
, never_subscribed
).
Jusqu'à présent, je pensais que le meilleur moyen était de les stocker dans la base de données, mais j'ai l'impression qu'il est beaucoup plus facile de les avoir dans les 3 autres options.
J'ai également pensé que je pouvais les stocker dans mon modèle Eloquent
sous forme de constantes. Par exemple, mon modèle d'abonnement ressemblerait à ceci:
// SubscriptionModel
const SUBSCRIBED_ACTIVE = 1;
const SUBSCRIBED_ON_GRACE_PERIOD = 2;
const NOT_SUBSCRIBED = 3;
const NEVER_SUBSCRIBED = 4;
et les récupérer, par exemple dans une vue de lame:
// 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
Pourquoi ne pas en faire autant, mais en utilisant le dossier config et en ajoutant un fichier appelé status.php
. Accéder à la vue serait comme:
@if($user->subscription->status == Config::get('status.subscription.SUBSCRIBED_ACTIVE'))
<div>You are subscribed. Thank you</div>
@elseif(...)
// etc
Y a-t-il un meilleur moyen?
Aussi, que diriez-vous de l’autre partie de l’équation, c’est-à-dire le statut stocké dans la variable DB
. Devrais-je avoir seulement une colonne status
pour la table d'abonnement et stocker ce que l'application dicte ou même mieux créer une table séparée subscription_statuses
et avoir un foreign_key
subscription_status_id
dans la table subscriptions
?
J'ai tendance à créer un modèle spécifique pour les statuts, qui agit comme une énumération. Donc, si j’ai un modèle Event
, il est possible qu’un modèle EventStatus
correspondant ressemble à ceci:
class EventStatus
{
const CANCELLED = 'EventCancelled';
const POSTPONED = 'EventPostponed';
const RESCHEDULED = 'EventRescheduled';
const SCHEDULED = 'EventScheduled';
}
Je peux alors faire des contrôles comme ceci:
$event->status == EventStatus::CANCELLED;
Et d’habitude, j’ajouterai également des méthodes pratiques à mes modèles:
class Event extends Model
{
public function isCancelled()
{
return $this->status == EventStatus::CANCELLED;
}
}
Pour les chaînes «conviviales pour l’homme», j’aurai alors un fichier de langue contenant les chaînes de texte:
<?php // resources/lang/en/event_status.php
return [
EventStatus::CANCELLED => 'Cancelled',
EventStatus::POSTPONED => 'Postponed',
EventStatus::RESCHEDULED => 'Rescheduled',
EventStatus::SCHEDULED => 'Scheduled',
];
Je ne suis pas d'accord avec les autres réponses. Vos informations de statut doivent être stockées dans la base de données. Une base de données bien conçue doit être claire et utilisable sans l'application. Que se passe-t-il si vous décidez d'utiliser cette base de données pour alimenter également quelque chose comme une application mobile? Vous allez retirer certaines informations de la base de données et les stocker uniquement dans Laravel, ce qui signifie que vous devez également dupliquer cette liste de statuts dans votre application mobile et la conserver dans les deux cas.
Ce type d'information devrait être stocké dans la base de données.
Option 1
Si vos utilisateurs ne peuvent avoir qu'un seul statut, vous devez utiliser un champ enum
avec les valeurs subscribed
, subscribed-grace
, not-subscribed
, never-subscribed
.
C’est aussi simple dans vos vues:
@if($user->subscription->status == 'subscribed'
Option 2
Si, toutefois, vous pouvez avoir plusieurs statuts, alors vous devriez presque certainement avoir un champ séparé pour chaque statut et utiliser un TINYINT
pour stocker un 1
ou un 0
.
Tableau d'état séparé?
Je ne vois pas de bonne raison d'utiliser une table d'état distincte à moins que vous ne prévoyiez ajouter beaucoup plus d'états. Même si vous en ajoutez d'autres, vous pouvez simplement ajouter de nouvelles valeurs à la variable enum
ou ajouter un nouveau champ, selon l'option qui conviendrait. .
Une table de statut serait idéale si vous envisagez d'utiliser les statuts pour de nombreuses autres tables de la base de données autres que les utilisateurs.
Si vous décidiez de modifier la signification d'un statut particulier, la seule autre raison justifiant la création d'une table d'état distincte serait. Cela signifierait que vous pourriez renommer le statut dans la table de statut, mais que les utilisateurs y seraient toujours liés via sa clé primaire. Changer la signification d'un statut avec les deux méthodes précédentes impliquerait des changements dans la structure.
Cela dépend vraiment de la manière dont vous prévoyez de les utiliser, mais il n’ya aucune raison de ne pas les conserver dans la base de données.
Dans mes applications, je fais similaire à @Martin Bean sauf que je ne crée pas de classes séparées pour status, je les stocke dans la classe/modèle existant.
Je vais appeler user
, subscription
et entity
une entité .
status
qui existe dans son modèle et une table dans la base de données.status
comme ACTIVE
, INACTIVE
, PENDING
, etc., et celles-ci peuvent varier pour chaque modèle.getStatusLabel()
, listStatus()
, isActive()
, isX()
, etc.isActive/X()
ne sont créés que si cela est vraiment nécessaire. Par exemple, un modèle a un statut 4, mais vous ne faites que des comparaisons avec un spécifique. Par conséquent, je ne créerais qu'un isX()
pour ce statut.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;
}
}
Chaque méthode présente des avantages et des inconvénients. C'est bien d'être au courant de chacun.
Tableau - Avantages et inconvénients (méthode d'AJReading):
Utilisation de constantes : Avantages/inconvénients (méthode de Martin Bean):
J'utilise la méthode constante mais parfois je pensais que mon code serait plus propre et plus simple si j'avais utilisé des tableaux. C'est un appel difficile. J'aimerais qu'il y ait une solution bien documentée pour que la méthode constante crée au moins de la cohérence, mais je n'en ai pas encore vu. De toute façon, je ne pense pas qu'il y ait une bonne ou une mauvaise réponse. Choisissez-en un et allez-y!
Pour des décisions de cette nature, demandez-vous ceci:
"Y aura-t-il un cas dans mon application où il serait logique Que ces constantes aient des valeurs différentes?"
par exemple. un environnement de test, une sorte de clone, des versions non encore définies mais des versions futures possibles ...
Si la réponse à cette question est "oui", alors il devrait probablement aller dans la configuration d'application.
S'il est peu probable (ou stupide) que les valeurs changent, elles appartiennent et doivent être intégrées au modèle.
Je suggère que dans ce cas, il n’y aurait aucune raison valable d’avoir une version de l’application avec des valeurs différentes, je la mettrais donc dans le modèle.