2016-10-23 92 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; 
}