2016-10-23 12 views
2

Vehicle車種が異なる(モデル番号はvehicles)モデルを持っているとしましょう。もちろん、そこに車の多くの異なる種類がありますので、私は、たとえばありますEloquentモデルに基づいて子孫クラスを作成する

class Car extends Vehicle { 
} 

class Bicycle extends Vehicle { 
} 

のように。

車に基づいたオブジェクトを見つける必要があります。ここに問題があります。

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

ので、私は、私が使用する必要があるクラス名を見つけることができます:私はVehicleモデルで次のメソッドを追加しました。

は、しかし、有効なクラスを取得する唯一の方法は、このようなものです:

私は、有効な最後のクラスオブジェクトを取得するには2つのまったく同じクエリを実行する必要があるため、最善の解決策ではありません
$vehicle = Vehicle::findOrFail($vehicleId); 
$vehicle = ($vehicle->getClass())::find($vehicleId); 

クエリを複製せずに同じことを達成する方法はありますか?正しくタイプ列によって決定クラスのオブジェクトを返すように雄弁ためには

+0

彼らはすべて異なるテーブルから来ているのですか、それともただ1台の車両テーブルですか? –

+0

これはデータベースの1つのテーブル –

答えて

1

代替を@にjedrzej.kuryloの方法は自分のVehicleクラスで1つのメソッドをオーバーライドすることです:

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; 
} 
関連する問題