我需要一组具有相同数据库表的模型,但它们需要以不同的方式实现某些方法。给定一组这样的类:
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
类中,根据实例类型运行不同的代码,很乱如果您有一列指示模型的类型,请尝试使用
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);
}
}