Marcin Nabiałek Marcin Nabiałek - 1 month ago 6
PHP Question

Create descendant class based on Eloquent model

Let's say I have

Vehicle
model (it's Eloquent model) that stores different types of vehicles (in
vehicles
table). Of course, there are many different types of vehicles, so I have for example:

class Car extends Vehicle {
}

class Bicycle extends Vehicle {
}


and so on.

now I need to find object based on vehicle and here's the problem. I've added the following method in
Vehicle
model:

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


so I can find the class name I should use.

But the only way to get valid class is like this:

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


which is not the best solution because I need to run 2 exact same queries to get valid final class object.

Is there any way to achieve same without duplicating the query?

Answer

An alternative to @jedrzej.kurylo's method would be to just override one method in your Vehicle class:

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

Hope this helps!