I need to extensively use statuses in mt project. I need them for my users
(active
, suspended
, etc), an entity (active
, pending_activation
, inactive
) and for my subscriptions(active
, on_grace_period
, not_subscribed
, never_subscribed
).
So far I thought that the best way is to store them in the DB but i have a feeling it's much easier to have them in the other 3 options.
I also thought that i can store them in my Eloquent
Model as constants. For example my subscription model would look like this:
// SubscriptionModel
const SUBSCRIBED_ACTIVE = 1;
const SUBSCRIBED_ON_GRACE_PERIOD = 2;
const NOT_SUBSCRIBED = 3;
const NEVER_SUBSCRIBED = 4;
and retrieving them, for example in a blade view:
// 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
How about doing the same but using the config folder and adding a file called status.php
. Accessing it in the view would be like:
@if($user->subscription->status == Config::get('status.subscription.SUBSCRIBED_ACTIVE'))
<div>You are subscribed. Thank you</div>
@elseif(...)
// etc
Is there a better way?
Also, how about the other part of the equation, meaning the status stored in the DB
. Should I only have a status
column for the subscription table and store what the app dictates or even bettter create a separate table subscription_statuses
and have a foreign_key
subscription_status_id
in the subscriptions
table?
I tend to create a specific model for statuses, that acts as an enum. So if I have an Event
model, I may have a corresponding EventStatus
model that looks like this:
class EventStatus
{
public const CANCELLED = 'EventCancelled';
public const POSTPONED = 'EventPostponed';
public const RESCHEDULED = 'EventRescheduled';
public const SCHEDULED = 'EventScheduled';
}
I can then do checks like this:
$event->status === EventStatus::CANCELLED;
And I’ll usually add convenience methods to my models too:
class Event extends Model
{
public function isCancelled(): bool
{
return $this->status === EventStatus::CANCELLED;
}
}
For the “human-friendly” strings, I’ll then have a language file that has the text strings:
<?php // resources/lang/en/event_status.php
return [
EventStatus::CANCELLED => 'Cancelled',
EventStatus::POSTPONED => 'Postponed',
EventStatus::RESCHEDULED => 'Rescheduled',
EventStatus::SCHEDULED => 'Scheduled',
];
In my applications I do similar to @Martin Bean except I don't create separate classes for status, I store that inside the existent class/Model.
I'm going to call user
, subscription
and entity
a entity.
status
that exists in it's Model and table in the database.status
like ACTIVE
, INACTIVE
, PENDING
, etc, and those may vary for each Model.getStatusLabel()
, listStatus()
, isActive()
, isX()
, etc.isActive/X()
are only created if really necessary, maybe a Model have 4 status but you only do comparisons against one specific, so I'd create only one isX()
for that status.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;
}
}
I do not agree with the other answers. Your status information should be stored in the database. A well designed database should be clear and usable without the application. What happens if you decide to use this database to power something like a mobile application as well? You will be taking some of the information away from the database and storing it only in Laravel, meaning you would have to duplicate that list of statuses in your mobile application too, and maintain it across the two.
This kind of information should be stored in the database.
Option 1
If your users can only ever have one status, then you should use an enum
field with the values subscribed
, subscribed-grace
, not-subscribed
, never-subscribed
This is just as simple in your views:
@if($user->subscription->status == 'subscribed'
Option 2
If however, you might have multiple statuses, then you should almost certainly have a separate field for each status, and use a TINYINT
to store a 1
or 0
.
Separate status table?
I cannot see a good reason to use a separate status table unless you anticipate you might add many more statuses, and even if you are adding more, you can just add new values to the enum
or add a new field depending on which option would suit.
A status table would be ideal if you plan to use the statuses for many other tables in the database besides users.
The only other reason for a seperate status table would be if you decided to change the meaning of a particular status. This would mean you could rename the status in the status table, but the users would still be linked to it via it's primary key. Changing the meaning of a status with the previous two methods would involve changes to the structure.
It really comes down to how you anticipate you will use them, but there is no reason not to keep them in the database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With