【问题标题】:Laravel 8: Get the class names of all Models that "morphOne" class of a specific relationLaravel 8:获取特定关系的“morphOne”类的所有模型的类名
【发布时间】:2021-09-10 13:40:54
【问题描述】:

我需要一个与另一个特定模型具有 OneToOne 或 OneToMany 多态关系定义的所有模型的类名列表。这个列表不能基于对应数据库表中实际存在的关系,而是基于代码定义。

示例

A、B 和 C 类与 X 类(*able 类)具有多态的一对一或一对多关系。

我正在搜索(现有的?)方法来检索 A、B 和 C(或与 X 具有相同关系的任何其他类)的类名。

【问题讨论】:

    标签: laravel polymorphism relationship one-to-many one-to-one


    【解决方案1】:

    MorphOne 关系的逆是MorphTo 关系。但是,在 Eloquent 中,这种关系并没有定义与自身具有 MorphOne 关系的所有模型。

    解决方案 A

    一个简单的解决方案是在 X 类上记录一个静态数组,该数组包含该关系的所有可能类,就像这样。

    class X extends Model
    {
        public static array RELATION_OPTIONS = [
            App\A::class,
            App\B::class,
            App\C::class,
        ];
    
        public function foo(): MorphTo
        {
            return $this->morphTo();
        }
    }
    

    此解决方案的缺点是您必须使模型选项数组与反向关系的实际实现保持同步。因此,每当您将具有MorphOne 关系的另一个模型添加到X 时,您都需要将其添加到RELATION_OPTIONS 数组中。

    解决方案 B

    另一种解决方案是使用循环所有Models 来确定它们中的哪些与X 有关系。在伪代码中,这意味着您将不得不这样做:

    $models = get_all_models(); // \Illuminate\Support\Collection
    $models->filter(function (Model $model) {
        if ( ! method_exists($model, 'foo')) return false;
    
        $relation = $model->foo();
    
        if ( ! $relation instanceof MorphOne) return false;
    
        return $relation->getParent() instanceof X;
    });
    

    这是一个不太简单但更准确的解决方案,始终与实际实施保持同步。但请注意,您需要缓存此方法的执行,因为查找应用程序中的所有模型(通过循环文件系统)可能是一项昂贵的任务。

    【讨论】:

    • 嗨,erikgaal,非常感谢您的解释。解决方案 A 就是我现在正在做的事情。解决方案 B 是我正在寻找的那种解决方案。是否有可能以某种方式使用 Laravel 缓存功能进行缓存?还是我必须自己实现一些东西。
    • 如果您将此逻辑抽象为某个方法,您可以通过在模型上使用静态属性“缓存”它并确保只设置一次(在启动时或需要该属性时) )。这样,每个请求只运行一次。另一种方法是使用 Laravel 的 Cache 系统,但这会使它再次变得更加复杂。
    猜你喜欢
    • 2014-12-05
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 2013-09-20
    • 2021-12-18
    相关资源
    最近更新 更多