Laravel-где хранить статусы (флаги)? Модель, класс или папка конфигурации?

мне нужно широко использовать статусы в проекте mt. Они нужны мне для моего users (active, suspended и т. д.), объект (active, pending_activation, inactive) и "мои подписки" (active, on_grace_period, not_subscribed, never_subscribed).

до сих пор я думал, что лучший способ-хранить их в БД, но у меня такое чувство, что их гораздо проще иметь в других 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. Должен ли я иметь только для подписка таблицы и хранить то, что приложение диктует или даже лучше создать отдельную таблицу subscription_statuses и foreign_key subscription_status_id на subscriptions таблицы?

5 ответов


Я склонен создавать определенную модель для статусов, которая действует как перечисление. Итак, если у меня есть 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';
];

Я не согласен с другими ответами. Информация о состоянии должна храниться в базе данных. Хорошо разработанная база данных должна быть четкой и полезной без применения. Что произойдет, если вы решите использовать эту базу данных для питания чего-то вроде мобильного приложения? Вы будете брать часть информации из базы данных и хранить ее только в Laravel, то есть вам придется дублировать этот список статусов в своем мобильном приложении и поддерживать его через пара.

подобного рода информация должна храниться в базе данных.

1

если ваши пользователи могут иметь только один статус, то вы должны использовать enum поле со значениями subscribed, subscribed-grace, not-subscribed, never-subscribed

это просто Ваше мнение:

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

2

Если, однако, у вас может быть несколько статусов, то вы должны почти конечно, есть отдельное поле для каждого статуса, и использовать TINYINT в магазине 1 или 0.

отдельная таблица состояния?

Я не вижу веской причины использовать отдельную таблицу состояния, если вы не ожидаете, что можете добавить еще много статусов, и даже если вы добавляете больше, вы можете просто добавить новые значения в enum или добавить новое поле в зависимости от того, какой вариант устроил бы.

таблица состояния была бы идеальной, если вы планируете использовать статусы для многих других таблиц в базе данных, кроме пользователей.

единственная другая причина для отдельной таблицы состояния была бы, если бы вы решили изменить значение определенного статуса. Это означает, что вы можете переименовать статус в таблице status, но пользователи все равно будут связаны с ним через первичный ключ. Изменение значения статуса с помощью двух предыдущих методов повлечет за собой изменения структуры.

это действительно сводится к тому, как вы ожидаете вы будете использовать их, но нет причин не хранить их в базе данных.


в моих приложениях я похож на @Martin Bean, за исключением того, что я не создаю отдельные классы для статуса, я храню это внутри существующего класса/модели.

Я позвоню user, subscription и entity a сущности.

  • сущности есть status который существует в его модели и таблице в базе данных.
  • каждая модель имеет константы возможных значений status как ACTIVE, INACTIVE, PENDING, etc, и они могут отличаться для каждой модели.
  • создать методы для борьбы с ним, как getStatusLabel(), listStatus(), isActive(), isX(), etc.
  • те isActive/X() создаются только при необходимости, возможно, модель имеет статус 4, но вы делаете сравнения только с одним конкретным, поэтому я бы создал только один isX() для этого статуса.

пример

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):

  • добавление и поддержание таблицы кажется утомительным
  • просто наличие другой таблицы и модели может сделать наш код более загроможденным (не говоря, что это хорошая причина не использовать просто сказать, что это правда)
  • становится неудобно, когда у нас есть логика приложения, зависящая от чего-то в база данных (вещи в базе данных чувствуют, что они должны быть переменными, когда мы основываем логику приложения на них, они необходимы)
  • теперь у нас есть миграции, но до них они были проклятием существования разработчиков (они сделали бы переключение между серверами ужасной рутиной, потому что вы должны были помнить, чтобы добавить новые статусы или ваше приложение рухнет)...вам пришлось бы сделать это с любым изменением базы данных, но все же это были те, которые мне нужно было сделать больше всего часто
  • хорошо для целостности данных

используя константы: плюсы /минусы (метод Мартина Бина):

  • избегает недостатков выше
  • на них легко ссылаться в вашем коде и базовой логике на
  • вам не нужно создавать новую модель или таблицу даже (он делает в своем примере, но вы также можете просто поместить их в модель событий)
  • они отлично подходят для значений, которые будут использоваться только за сцены
  • они уменьшают количество запросов
  • они просто не чувствуют, как много работы. Они, кажется, проще рефакторить.
  • Кон: они вам как-то неловко, когда ты попадешь в их маркировку, получая их, становится легендой, и т. д. Решение перевода является хорошим, но если вы не используете переводы в своем приложении, то это немного неудобно.
  • в конечном счете они нарушают поток ORM, который у вас есть. Если все ваши другие модели расширяются Красноречиво тогда это немного ломает форму.
  • нет реального соглашения о том, как лучше всего это сделать. Многие люди используют разные методы каждый раз.
  • как сказал AJReading, если вам нужно использовать базу данных только для другого аспекта проекта, он не будет работать

Я использую метод constant, но иногда я думаю, что мой код мог бы быть чище и проще, если бы я использовал таблицы. Это трудный вызов. Я хотел бы, чтобы было хорошо документированное решение для константы метод, по крайней мере, для создания согласованности, но я его еще не видел. В любом случае я не думаю, что есть правильный или неправильный ответ. Выберите один и идите с ним!


для решения такого рода, спросите себя:

"будет ли когда-нибудь экземпляр моего приложения, где это сделать смысл для этих констант иметь разные значения?"

например, тестовая среда, какой-то клон, некоторые еще не определены, но возможная будущая версия...

Если ответ на этот вопрос "да", то он, вероятно, должен идти в конфигурации приложения.

Если маловероятно, (или daft) иметь значения меняются, они принадлежат и должны идти в модели.

Я предполагаю, что в этом случае не было бы разумной причины когда-либо иметь версию приложения с разными значениями, поэтому я бы поместил ее в модель.