【问题标题】:One to many polymorphic relationship一对多多态关系
【发布时间】:2019-01-26 17:31:16
【问题描述】:

这是一种常见的情况,但到目前为止我不知何故无法找到合理的解决方案。基本上我需要以下内容: 我有模型House,其中包含几个其他模型(例如Brick、'Stick'、'Chair' 等)。他们每个人都与 House 有一个 belongsTo 关系(所以基本上在stickschairsbricks 表中有一个house_id 列)。每个模型都包含一个public function house() 方法,该方法返回它们所属的房子。现在出现的问题是,我想通过一种方法获取房屋的所有用品,例如public function supplies(),它应该返回类StickChairBrick 的实例集合。有什么方便的方法可以实现吗?例如,我是否可以通过一个特征将这些类联合起来,并以某种方式在房子的方法中指向该特征,或者可能使用一个 BaseClass,比如说Supply,所有的供应都应该继承?有什么建议吗?非常感谢任何帮助,并在此先感谢!

【问题讨论】:

    标签: eloquent polymorphism laravel-5.4 relationship


    【解决方案1】:

    Laravel 对此没有内置支持。

    您可以定义单独的HasMany 关系,然后将它们与accessor 合并:

    class House extends Model {
        public function bricks() {
            return $this->hasMany(Brick::class);
        }
    
        public function chairs() {
            return $this->hasMany(Chair::class);
        }
    
        public function sticks() {
            return $this->hasMany(Stick::class);
        }
    
        public function getSuppliesAttribute() {
            return $this->bricks->toBase()->merge($this->chairs)->merge($this->sticks);
        }
    }
    
    $supplies = $house->supplies;
    

    +++更新+++

    我创建了一个使用视图合并关系的包:
    https://github.com/staudenmeir/laravel-merged-relations

    首先,在迁移中创建合并视图:

    use Staudenmeir\LaravelMergedRelations\Facades\Schema;
    
    Schema::createMergeView(
        'supplies', [(new House)->bricks(), (new House)->chairs(), (new House)->sticks()]
    );
    

    然后定义关系:

    class House extends Model
    {
        use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;
    
        public function supplies()
        {
            return $this->mergedRelation('supplies');
        }
    }
    

    像任何其他关系一样使用它:

    House::find($id)->supplies;
    
    House::find($id)->supplies()->paginate();
    
    House::with('supplies')->get();
    

    【讨论】:

    • 我想到了完全相同的解决方案,唯一的问题是我在整个经历中遇到的一个小情况。通过访问器干扰数据库给我带来了严重的错误问题,当创建未连接到数据库或什至不作为条目存在的类的新实例时,这是供应商级别的一些严重问题。您确定这将是一种安全的方法吗?或者,我可以为此目的初始化一个方法,但是我会失去任何类型的关系功能。有什么想法吗?
    • 访问器方法只能用于检索数据。如果您需要完整的关系支持,您可能必须编写自己的关系类型。
    • 是的,我也想到了...我将继续尝试这种方法,但我仍然对访问器中的关系工作有些怀疑,因为如前所述,我以前在将它们与类的非数据库绑定实例一起使用时遇到了大量trying to get property of null 错误。谢谢你的回答!
    • House 类的非数据库绑定实例?
    • 我创建了一个用于合并关系的包并将其添加到我的答案中。
    猜你喜欢
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2021-11-14
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多