【问题标题】:SoftDeletes do not filter when using a boot method in a model在模型中使用引导方法时,SoftDeletes 不会过滤
【发布时间】:2016-03-09 23:52:39
【问题描述】:

我有一个在 Laravel 中使用软删除的 Model,它还使用了一个包含 boot 函数的特征:

class Design extends Model {
    uses Softdeletes, Versionable;
    // ...
}

trait Versionable {
    public static function boot(){
    // ...
    }
}

SoftDeletes 本身仍然有效:deleted_at 列被正确填充。但是,Designs::get() 没有正确过滤软删除模型:

return Designs::get();

[{"id":1,"project_id":1,"name":"","description":null,"created_at":"2015-12-04 21:06:40","updated_at":"2015-12-04 21:06:40","deleted_at":null},
 {"id":2,"project_id":1,"name":"A Design","description":"a different description", "created_at":"2015-12-04 21:06:57","updated_at":"2015-12-04 21:07:09","deleted_at":"2015-12-04 21:07:09"}]

从 Versionable 中删除 Versionable 特征或 boot 方法可以解决问题。

为什么会发生这种情况,我该如何解决?

【问题讨论】:

    标签: php laravel soft-delete


    【解决方案1】:

    首先,我假设您没有在 trait 的 boot 方法中调用 parent::boot();,这就是您遇到此问题的原因。您正在覆盖父级的引导方法。但是,出于几个原因,我不会推荐这种方法,而 Laravel 实际上推荐在向 trait 添加引导方法时使用标准命名约定。

    如果您的 trait 有 boot 方法,它将覆盖父模型的 boot 方法。你可以在 trait 的 boot 方法中添加一个 parent::boot(); 方法来解决这个问题,这样它也会调用父级的 boot 方法。然而,如果你的模型有一个boot 方法,它基本上会删除特征的启动方法。向您的 trait 添加启动方法会产生潜在的冲突,无论是现在、以后,还是其他人尝试使用您的 trait。

    为了解决这个问题,Laravel 建议你将 trait 的启动方法命名为以下格式:boot{TraitName}

    换句话说,您的 Trait 称为 Versionable,因此如果您将引导方法重命名为以下代码,您的代码将正常工作:

    public static function bootVersionable(){
        // ...
    }
    

    编辑:Source

    如果 Eloquent 模型使用的 trait 具有与 bootNameOfTrait 命名约定匹配的方法,则该 trait 方法将在 Eloquent 模型启动时被调用,让您有机会注册全局作用域,或做任何您想做的事情。

    【讨论】:

    • 谢谢您,这非常有效。你有 Laravel 提出此建议的链接或来源吗?
    • 我不知道为什么 L5.1 的文档中没有提到它,但在 L5.0 的文档中简要提到了它。我已经编辑了。:)
    猜你喜欢
    • 2022-11-22
    • 2014-09-02
    • 2013-06-29
    • 2011-03-03
    • 1970-01-01
    • 2021-06-08
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多