【问题标题】:Laravel timestamps keep track of who has done certain action (like created_at & created_by, updated_at & updated_by)Laravel 时间戳跟踪谁做了某些动作(比如 created_at & created_by, updated_at & updated_by)
【发布时间】:2021-12-18 14:27:06
【问题描述】:

在我的应用程序中,我想跟踪谁在我的应用程序中对不同模型执行了某些操作。

带有时间戳的默认 Laravel 模型会自动更新 created_atupdated_at 等字段。我可以修改此行为以通过调用此答案中提到的 static::updating() 函数自动设置 created_by 字段:https://stackoverflow.com/a/64241347/4112883 。这很好用。此外,我遇到了这个包 (https://github.com/WildsideUK/Laravel-Userstamps),但仅限于创建、更新和删除。

对于我的 Post 模型,我有更多时间戳:created_at、updated_at、completed_at、checked_at 和 published_at。当用户结束帖子时,必须由该用户的经理验证。如果一切顺利,一些逻辑将发布消息,但如果没有,管理器可以创建一个或多个动作让用户完成消息,这将撤消整理属性。使用以下时间戳创建操作:已创建、已更新和已完成 (null)。当用户完成一个动作时,actions.finished_at 和 actions.finished_by 字段被设置。

现在挑战来了。对于每个自定义时间戳,我想设置关系和三个函数来处理时间戳的某些状态:设置、撤消和检查 isset:

class Post extends Model
{

  //…

  public function finishedBy() //relationship belongsTo User::class
  {
    return $this->belongsTo(User::class, 'finished_by');
  }


  public function finish() { //function to finish post (SET)
    $this->update([
            'finished_by' => auth()->id(),
            'finished_at' => now(),
        ]);

  }

  public function undoFinish() { //function to undo finishing (UNSET)
    $this->update([
            'finished_at' => null,
            'finished_by' => null,
        ]);
  }

  public function isFinished() { //function to check if is finished (ISSET)
    return !empty($this->finished_by) && !empty($this->finished_at);
  }

  //…

对于 Post 模型中的 ‘checked’ 和 ‘published’ 以及 Action 模型中的 ‘finished’ 属性必须重复所有四个函数,从而导致大量几乎重复的代码。 (也许将来我想在其他模型中重复这个逻辑。)

是否有可能通过 Trait 或其他东西使它更优雅?

例如创建一个类似于受保护数组 $timestamps_with_user 的东西,应用程序通过它自动添加关系和三个函数?


  protected $timestamps_with_users = [
    'finish', 'check', 'publish'
  ];


  // foreach in a trait?? Need your help here :D
  foreach($timestamps_with_users as $perform) {

    public function $perform() { … } //$post->finish()
    public function $perform.edBy() :User { … } //$post->finishedBy() 
    public function undo.$perform() { … } //$post->undoFinish()
    public function is.$perform.ed() { … } //$post->isFinished()

  }

提前致谢,期待您的回答。

【问题讨论】:

    标签: php laravel timestamp


    【解决方案1】:

    只需创建一个新特征并创建适用于任何时间戳的函数:

       <?php
        namespace App\Traits;
        trait CustomTimestamps {
            public function perform(string $action)
            {
                $this->update([
                    $action . 'ed_by' => auth()->id(),
                    $action . 'ed_at' => now(),
                ]);
            }
    
            public function undo(string $action)
            {
                $this->update([
                    $action . 'ed_by' => null,
                    $action . 'ed_at' => null,
                ]);
            }
    
            public function check(string $action)
            {
               $at = $action . 'ed_at';
               $by = $action . 'ed_by';
               return !empty($this->{$by}) && !empty($this->{$at});
            }
        }
    

    【讨论】:

    • 不可能循环遍历数组来生成函数吗?以及如何通过 trait 生成关系函数 performBy :User?你是不是故意漏掉的?
    猜你喜欢
    • 2019-01-22
    • 2016-08-28
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    相关资源
    最近更新 更多