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

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

До сих пор я думал, что лучший способ — хранить их в БД, но у меня есть ощущение, что гораздо проще иметь их в трех других вариантах.

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

15

Решение

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

Другие решения

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

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

Опция 1

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

Это так же просто в ваших взглядах:

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

Вариант 2

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

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

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

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

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

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

6

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

Я собираюсь позвонить user, subscription а также entity юридическое лицо.

  • сущность иметь status который существует в его модели и таблицы в базе данных.
  • Каждая модель имеет константы возможных значений status лайк ACTIVE, INACTIVE, PENDINGи т. д., и они могут различаться для каждой модели.
  • Создать методы для борьбы с этим, как getStatusLabel(), listStatus(), isActive(), isX(), так далее.
  • Те 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;
}
}
3

У каждого метода есть свои преимущества и недостатки. Хорошо быть в курсе каждого.

Таблица — Плюсы и минусы (метод AJReading):

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

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

  • Избегает недостатков выше
  • Это легко ссылаться в вашем коде и базовой логике на
  • Вам даже не нужно создавать новую модель или таблицу (он это делает в своем примере, но вы также можете просто поместить их в модель Events)
  • Они отлично подходят для ценностей, которые будут использоваться ТОЛЬКО за кулисами
  • Они уменьшают количество запросов
  • Им просто не хочется много работать. Они кажутся проще для рефакторинга.
  • Против: они становятся немного неловкими, когда вы их помечаете, извлекаете их все, получаете описания и т. Д. Решение для перевода — это хорошо, но если вы не используете переводы в своем приложении, то это тоже немного неловко.
  • В конечном итоге они нарушают поток ORM, который у вас есть. Если все ваши другие модели расширяют Eloquent, это немного ломает форму.
  • Там нет реального соглашения о том, как лучше всего это сделать. Многие люди используют разные методы каждый раз.
  • Как сказал AJReading, если вам нужно использовать базу данных отдельно для другого аспекта проекта, она не будет работать

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

1

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

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

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

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

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

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

0
По вопросам рекламы [email protected]