2016-10-23 59 views
2

比方说,我有Vehicle模型(它是Eloquent模型),它存储不同类型的车辆(在vehicles表中)。当然,有很多不同类型的车辆,所以我举例如下:基于Eloquent模型创建后代类

class Car extends Vehicle { 
} 

class Bicycle extends Vehicle { 
} 

等等。

现在我需要找到基于车辆的对象,这里的问题。我已经添加了以下方法Vehicle模型:

public function getClass() 
{ 
    return __NAMESPACE__ . '\\' . ucfirst($this->type) 
} 

这样我就可以找到类的名字,我应该使用。

但要获得有效的类唯一的办法是这样的:

$vehicle = Vehicle::findOrFail($vehicleId); 
$vehicle = ($vehicle->getClass())::find($vehicleId); 

,因为我需要运行2个完全相同的查询,以获得有效的最后一类对象,它是不是最好的解决方案。

有没有什么办法可以在不重复查询的情况下实现同样的功能?

+0

他们都来自不同的桌子还是只有1个车辆表? –

+0

它是数据库中的一个表 –

回答

1

的替代@ jedrzej.kurylo的方法是只覆盖一个方法,你Vehicle类:

public static function hydrate(array $items, $connection = null) 
{ 
    $models = parent::hydrate($items, $connection); 

    return $models->map(function ($model) { 

     $class = $model->getClass(); 

     $new = (new $class())->setRawAttributes($model->getOriginal(), true); 
     $new->exists = true; 

     return $new; 
    }); 
} 

希望这有助于!

+0

谢谢,我认为这是更好的解决方案(只有我自定义的方法),但它远不如@ jedrzej.kurylo明显,可能我永远不会试图重写此:) –

1

为了雄辩正确返回由列,来确定一个类的对象,你需要重写你的车辆模型类2种方法:

public function newInstance($attributes = array(), $exists = false) 
{ 
    if (!isset($attributes['type'])) { 
    return parent::newInstance($attributes, $exists); 
    } 

    $class = __NAMESPACE__ . '\\' . ucfirst($attributes['type']); 

    $model = new $class((array)$attributes); 
    $model->exists = $exists; 

    return $model; 
} 

public function newFromBuilder($attributes = array(), $connection = null) 
{ 
    if (!isset($attributes->type)) { 
    return parent::newFromBuilder($attributes, $connection); 
    } 

    $instance = $this->newInstance(array_only((array)$attributes, ['type']), true); 

    $instance->setRawAttributes((array)$attributes, true); 

    return $instance; 
}