我们说我有Vehicle
模型(它的Eloquent模型),它存储不同类型的车辆(在vehicles
表中)。当然,有许多不同类型的车辆,所以我有例如:
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)
为了让Eloquent正确返回由类型列确定的类的对象,您需要覆盖 Vehicle 模型类中的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;
}
答案 1 :(得分: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;
});
}
希望这有帮助!