Laravel - 在哪里存储状态(标志)?模型、类或配置文件夹?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32917944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:26:22  来源:igfitidea点击:

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

phpmysqllaraveleloquentstatus

提问by Cristian

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

我需要在 mt 项目中广泛使用状态。我的users( active, suspended, 等)、实体 ( active, pending_activation, inactive) 和订阅 ( 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.

到目前为止,我认为最好的方法是将它们存储在数据库中,但我觉得将它们放在其他 3 个选项中要容易得多。

I also thought that i can store them in my EloquentModel as constants. For example my subscription model would look like this:

我还认为我可以将它们Eloquent作为常量存储在我的模型中。例如,我的订阅模型如下所示:

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

如何做同样的事情,但使用 config 文件夹并添加一个名为status.php. 在视图中访问它就像:

@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 statuscolumn for the subscription table and store what the app dictates or even bettter create a separate table subscription_statusesand have a foreign_keysubscription_status_idin the subscriptionstable?

另外,等式的另一部分如何,这意味着存储在DB. 我应该只有status订阅表的列并存储应用程序指示的内容,还是最好创建一个单独的表subscription_statusesforeign_keysubscription_status_idsubscriptions表中包含一个?

采纳答案by Martin Bean

I tend to create a specific model for statuses, that acts as an enum. So if I have an Eventmodel, I may have a corresponding EventStatusmodel that looks like this:

我倾向于为状态创建一个特定的模型,作为一个枚举。所以如果我有一个Event模型,我可能有一个对应的EventStatus模型,看起来像这样:

class EventStatus
{
    const CANCELLED = 'EventCancelled';
    const POSTPONED = 'EventPostponed';
    const RESCHEDULED = 'EventRescheduled';
    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()
    {
        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',
];

回答by AJReading

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.

我不同意其他答案。您的状态信息应存储在数据库中。一个设计良好的数据库应该清晰可用,无需应用程序。如果您决定也使用此数据库来支持移动应用程序之类的东西,会发生什么情况?您将从数据库中取出一些信息并将其仅存储在 Laravel 中,这意味着您也必须在移动应用程序中复制该状态列表,并在两者之间进行维护。

This kind of information should be stored in the database.

这种信息应该存储在数据库中。

Option 1

选项1

If your users can only ever have one status, then you should use an enumfield with the values subscribed, subscribed-grace, not-subscribed, never-subscribed

如果您的用户只能有一个状态,那么您应该使用一个enum字段,其值为subscribed, subscribed-grace, not-subscribed,never-subscribed

This is just as simple in your views:

这在您的观点中同样简单:

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

Option 2

选项 2

If however, you might have multiple statuses, then you should almost certainly have a separate field for each status, and use a TINYINTto store a 1or 0.

但是,如果您可能有多个状态,那么您几乎可以肯定每个状态都有一个单独的字段,并使用 aTINYINT来存储 a10

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 enumor add a new field depending on which option would suit.

我看不出使用单独状态表的充分理由,除非您预计可能会添加更多状态,并且即使添加更多状态,您也可以enum根据适合的选项添加新值或添加新字段。

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.

这实际上取决于您预期将如何使用它们,但没有理由不将它们保留在数据库中。

回答by Edson Horacio Junior

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.

在我的应用程序中,我与@Martin Bean 类似,只是我不为状态创建单独的类,我将它存储在现有的类/模型中。

I'm going to call user, subscriptionand entitya entity.

我要呼吁usersubscriptionentity一个实体

  • Entityhave a statusthat exists in it's Model and table in the database.
  • Each Model have constants of possible values of statuslike ACTIVE, INACTIVE, PENDING, etc, and those may vary for each Model.
  • Create methods for dealing with it like getStatusLabel(), listStatus(), isActive(), isX(), etc.
  • Those 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.
  • 实体有一个status存在于它的模型和数据库中的表中。
  • 每个模型具有的可能值的常数status一样ACTIVEINACTIVEPENDING,等等,并且这些可为每个型号而变化。
  • 创建处理它类似的方法getStatusLabel()listStatus()isActive()isX(),等。
  • 这些isActive/X()仅在真正必要时创建,也许一个模型有 4 个状态,但您只与特定的一个进行比较,所以我只isX()为该状态创建一个。

Example

例子

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;
    }
}

回答by Sabrina Leggett

There are advantages and disadvantages to each method. It's good to be aware of each.

每种方法都有优点和缺点。了解每一个是很好的。

Table- Pros and cons (AJReading's method):

- 利弊(AJReading 的方法):

  • Adding and maintaining a table SEEMS tedious
  • Just having another table and model can make our code feel more cluttered (not saying it's a good reason not to use just saying it's kinda true)
  • It gets awkward when we have application logic dependent upon something in the database (things in the database feel like they should be variable, when we base application logic on them they're required)
  • Now we have migrations, but before them these used to be the bane of developers existence (they would make switching between servers an awful chore because you had to remember to add new statuses or your app would crash)...you would have had to do this with any database change but still these were the ones I'd have to do the most frequently
  • Good for data integrity
  • 添加和维护一个表似乎很乏味
  • 只是有另一个表和模型会让我们的代码感觉更混乱(并不是说这是不使用的一个很好的理由,只是说它有点真实)
  • 当我们的应用程序逻辑依赖于数据库中的某些东西时会变得很尴尬(数据库中的东西感觉它们应该是可变的,当我们将应用程序逻辑建立在它们之上时,它们是必需的)
  • 现在我们有了迁移,但在它们之前,这些曾经是开发人员存在的祸根(它们会使服务器之间的切换变得非常繁琐,因为您必须记住添加新状态,否则您的应用程序会崩溃)……您将不得不对任何数据库更改执行此操作,但这些仍然是我最常做的
  • 有利于数据完整性

Using constants: Pros/cons (Martin Bean's method):

使用常量:优点/缺点(Martin Bean 的方法):

  • Avoids the disadvantages above
  • These are easy to reference in your code and base logic on
  • You don't have to create a new model or table even (he does in his example, but you could also just put them in the Events model)
  • They're great for values that will ONLY be used behind the scenes
  • They reduce the amount of queries
  • They just don't feel like as much work. They seem easier to refactor.
  • Con: they get kinda awkward when you get into labeling them, retrieving all of them, getting descriptions, etc. The translation solution is a good one but if you don't use translations in your app then this is a bit awkward as well.
  • Ultimately they're breaking the ORM flow you have going. If all your other models extend Eloquent then this breaks the mold a bit.
  • There's no real agreement on how to best do this. A lot of people use a different method each time.
  • Like AJReading said, if you need to use the database alone for another aspect of the project it won't work
  • 避免上述缺点
  • 这些很容易在您的代码和基本逻辑中引用
  • 你甚至不必创建一个新的模型或表(他在他的例子中做了,但你也可以把它们放在事件模型中)
  • 它们非常适合仅在幕后使用的值
  • 他们减少了查询量
  • 他们只是觉得没有那么多工作。它们似乎更容易重构。
  • 缺点:当你给它们贴标签、检索所有它们、获取描述等时,它们会有点尴尬。翻译解决方案是一个很好的解决方案,但如果你不在你的应用程序中使用翻译,那么这也有点尴尬。
  • 最终,他们正在破坏您要进行的 ORM 流程。如果您的所有其他模型都扩展了 Eloquent,那么这会打破常规。
  • 关于如何最好地做到这一点并没有真正的共识。很多人每次都使用不同的方法。
  • 就像 AJReading 说的,如果您需要将数据库单独用于项目的另一个方面,它将不起作用

I use the constant method but sometimes I'd think my code might be cleaner and simpler if I'd used tables. It's a hard call. I'd like there to be a well documented solution for the constant method to at least create consistency but I haven't seen one yet. Either way I don't think there's a right or wrong answer. Pick one and go with it!

我使用常量方法,但有时我认为如果我使用表,我的代码可能会更清晰、更简单。这是一个艰难的电话。我希望有一个有据可查的解决方案,用于至少创建一致性的常量方法,但我还没有看到。无论哪种方式,我都认为没有正确或错误的答案。选择一个并使用它!

回答by DanSingerman

For decisions of this nature, ask yourself this:

对于这种性质的决定,问问自己:

"Will there ever be an instance of my application where it would make sense for these constants to have different values?"

“我的应用程序会不会有一个实例,让这些常量具有不同的值?”

e.g. a test environment, some sort of clone, some not yet defined but possible future version...

例如一个测试环境,某种克隆,一些尚未定义但可能的未来版本......

If the answer to that question is "yes", then it should probably go in application config.

如果该问题的答案是“是”,那么它可能应该在应用程序配置中。

If it is unlikely, (or daft) to have the values change, they belong to, and should go in the model.

如果不太可能(或愚蠢)使值发生变化,则它们属于并且应该进入模型。

I suggest in this case there would be no sensible reason to ever have a version of the application with different values, so I'd put it in the model.

我建议在这种情况下,没有合理的理由让应用程序版本具有不同的值,所以我将它放在模型中。