2016-08-01 6 views
0

Ich versuche, mein Routing für meine Modelle mit Laravel 5.1 zu vereinfachen. Ich habe zwei Ressourcen, Fragen und Kategorien, die von ResourceController erben.Laravel Routing mit Modell als String mit eifrigem Laden - Circular Reference

$router->get('/categories', 'Resources\[email protected]'); 
$router->get('/questions', 'Resources\[email protected]'); 

In ResourceController.php, verwenden Sie meine Ressourcenklassen dieses index Methode:

public function index(Request $request, Route $route) 
{ 
    // Converts route name into namespaced Model string 
    // E.g: App\Http\Controllers\Resources\[email protected] -> App\Question 
    $model = $this->getModelClass($route->getActionName()); 

    return $model::all(); 
} 

This SO post sagt, dass ich ein beredtes Methoden mit einem vollständig qualifizierten String anrufen:

$model_name = 'App\Model\User'; 
$model_name::where('id', $id)->first(); 

Wenn ich $model zurückkehren , Bekomme ich App\Category und App\Question für die jeweiligen Routen, die ich getroffen habe. Das ist gut!

Wenn ich $model::all() zurückgebe, erhalte ich einen 500 Fehler ohne Daten.

Ich überprüfte meine Sequel Pro Query Logger und sah, dass sowohl questions als auch categories etwa 20 Mal aufgerufen wurden, obwohl ich nur eine Route auf einmal anfordere.

enter image description here

Warum ist das passiert? Dies könnte den Fehler 500 erklären. Ich war in der Lage, die Modelle zu erhalten, wenn nur eine Ressource diese Eltern-index-Methode verwendet.

Wenn sowohl Questions als auch Categories auf demselben index stützten, begannen die Fehler. Ich sehe nicht, warum dies ein Konflikt ist, da die Route den spezifischen Aufruf an den Index mit dem Modellnamen sendet.


EDIT: Ich denke, das, wie eifrig Laden Ich Angabe verwandt ist:

Category.php Modell:

protected $with = ['questions']; 

Question.php Modell:

protected $with = ['category']; 

es also scheint ein Rundschreiben zu sein Referenz, wo Fragen zum Laden mit Kategorien kommen, die wiederum verwandte Fragen laden, und so weiter.

Aber ich brauche tatsächlich jedes mit der Relation zu laden. Wie kann ich das beheben?

Antwort

0

Die Antwort liegt here.

Es scheint in der Tat eine Zirkularreferenz zu sein.Eager Lasten auf die Abfrage, nicht auf das Modell passieren soll, wenn Sie ein generisches Modell loader wollen:

In meiner Modelle, änderte ich den $with auf eine Konstante, die ich laden kann:

class Category extends BaseModel 
{ 
    // Removed: protected $with = ['questions']; 
    const EAGER_LOAD = ['questions']; 

In der Übergeordnete Ressource-Controller, lade ich die Konstanten hier:

public function index(Request $request, Route $route) 
{ 
    $model = $this->getModelClass($route->getActionName()); 

    return $model->with($model::EAGER_LOAD)->get(); 
}