Laravel 与扩展模型的关系

问题描述 投票:0回答:1

我需要一组具有相同数据库表的模型,但它们需要以不同的方式实现某些方法。给定一组这样的类:

class Item {
    protected $table = 'items';
}
interface SubItem {
    public function foo();
}
class ItemA extends Item implements SubItem {
    public function foo(){
        do_abc();
    }
}
class ItemB extends Item implements SubItem {
    public function foo(){
        do_def();
    }
}
class ItemC extends Item implements SubItem {
    public function foo(){
        do_ghi();
    }
}
class Owner {
    public function items() {
        return $this->hasMany(Item::class);
    }
}

一切正常,直到我尝试获取

items()
关系。生成的实例被强制转换为
Item
类,并且我无法调用该函数。有一个
type
列指示模型是什么。

似乎我应该能够将

Item
声明为抽象,并使用类型列让关系返回
ItemA
ItemB
ItemC
实例的集合,但显然情况并非如此。我将来可能想添加任意数量的额外子类。 Laravel 有办法做到这一点吗?

考虑的替代方案:

  • 多态关系,似乎不能解决这种情况
  • 将方法添加到
    Item
    类中,根据实例类型运行不同的代码,很乱
  • 为每种类型添加关系,并使用“假”关系方法在幕后收集它们,这稍微不那么混乱
laravel eloquent eloquent-relationship
1个回答
0
投票

如果您有一列指示模型的类型,请尝试使用

newFromBuilder
方法创建
Item
的新实例作为正确的类型。我不确定哪个字段指定了您的情况下的模型类型,但我假设它是
type
:

class Item extends Model {
    protected $table = 'items';

    protected static $typeMapping = [
        'item_a' => ItemA::class,
        'item_b' => ItemB::class,
        'item_c' => ItemC::class,
    ];

    // Override the newFromBuilder method
    public function newFromBuilder($attributes = [], $connection = null)
    {
        // Map the 'type' value to a specific class
        $class = static::$typeMapping[$attributes->type] ?? self::class;

        return (new $class)->newInstance((array) $attributes, true);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.