phpmysqllaraveleloquentstatus

Laravel - Where to store statuses (flags)? Model, Class or config folder?


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?


Solution

  • 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',
    ];
    

    * Since I wrote this answer, PHP has introduced enumerations to the language: https://www.php.net/manual/en/language.types.enumerations.php