Php 基于雄辩模型创建子类

Php 基于雄辩模型创建子类,php,laravel,laravel-5,eloquent,laravel-5.3,Php,Laravel,Laravel 5,Eloquent,Laravel 5.3,假设我有车辆模型(这是一个雄辩的模型),它存储不同类型的车辆(在车辆表中)。当然,有许多不同类型的车辆,例如: class Car extends Vehicle { } class Bicycle extends Vehicle { } 等等 现在我需要找到基于车辆的对象,这就是问题所在。我在车型中添加了以下方法: public function getClass() { return __NAMESPACE__ . '\\' . ucfirst($this->type) }

假设我有
车辆
模型(这是一个雄辩的模型),它存储不同类型的车辆(在
车辆
表中)。当然,有许多不同类型的车辆,例如:

class Car extends Vehicle {
}

class Bicycle extends Vehicle {
}
等等

现在我需要找到基于车辆的对象,这就是问题所在。我在
车型中添加了以下方法:

public function getClass()
{
    return __NAMESPACE__ . '\\' . ucfirst($this->type)
}
所以我可以找到我应该使用的类名

但获得有效类的唯一方法如下所示:

$vehicle = Vehicle::findOrFail($vehicleId);
$vehicle = ($vehicle->getClass())::find($vehicleId);
这不是最好的解决方案,因为我需要运行两个完全相同的查询来获得有效的最终类对象


是否有任何方法可以在不重复查询的情况下实现相同的结果?

为了能够正确返回由type列确定的类的对象,您需要覆盖车辆模型类中的两种方法:

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;
}

@jedrzej.kurylo方法的另一个替代方法是只覆盖
车辆
类中的一个方法:

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;
    });
}

希望这有帮助

它们都来自不同的表还是只有一个Vehicles表?数据库中只有一个表谢谢,我认为这是更好的解决方案(只有我自定义的方法),但是它远不如@jedrzej.kurylo明显,也许我永远不会试图覆盖它:)