2013-02-27 3 views
1

Compte tenu des modèles suivants:Comment charger efficacement plusieurs relations has_many dans CodeIgniter DataMapper ORM?

Catégorie: has_many (« modèle ») Modèle: has_many (« tag », « procédure »)

Quelle est la façon la plus efficace de charger tous les objets liés à toutes les catégories ?

Par exemple, je suis en train de faire ce qui suit, mais nous espérons il y a une meilleure façon:

// Load all Category objects 
$categories = new Category(); 
$categories->get(); 

// Load all Template objects related to each Category 
foreach($categories as $category) 
{ 
    $category->templates->get(); 

    // Load all the Tag and Procedure objects related to each template 
    foreach($category->templates as $template) 
    { 
    $template->tags->get(); 
    $template->procedures->get(); 
    } 
} 

En ce moment, ce code est exécuté plus de 200 requêtes sur une page particulière.

+0

Est-ce que Datamapper a un type de chargement avide? ie: Model :: get (array ('include' => array ('tags', 'procedures'))). ou include_related méthodes? – Philip

+0

Oui, sous la forme de include_related, mais cela ne fonctionne pas pour has_many, car l'hydratation de Datamapper ne peut actuellement pas gérer la répétition dans le résultat de la requête. – WanWizard

+1

Existe-t-il un moyen plus efficace d'accomplir ceci? Je traite essentiellement de la même situation. Je charge environ 600 modèles, et j'aimerais inclure des modèles associés pour chacun d'entre eux, donc je suis en train de parcourir la première liste de modèles comme vous l'êtes, et d'exécuter 'get()' pour chacun d'entre eux. Le nombre de requêtes en cours d'exécution semble affecter la mémoire disponible sur ma machine. Y a-t-il un moyen plus efficace de le faire? – flyingL123

Répondre

0

Vous pouvez utiliser les éléments suivants

foreach($categories as $category) 
    { 
     // here you can use the $category object 
     foreach($category->templates as $template){ 
      // here you can use the $template object 
      foreach($template->tags as $tags){ 
       // here you can use the $tags object 
      } 
      foreach($template->procedures as $proceadures){ 
       // here you can use the $proceadures object 
      } 
     } 
    } 

Assurez-vous que vous avez activé l'option Remplir automatiquement dans l'application config DataMapper/config/datamapper.php et vous ne avez pas besoin d'exécuter get() sur tous les modèles

$config['auto_populate_has_many'] = TRUE; 
$config['auto_populate_has_one'] = TRUE; 

J'espère que ça aide!

+1

Alors que le remplissage automatique de toutes les relations has_many sera "efficace" dans la mesure où vous n'aurez pas à écrire autant de get() s, cela pourrait être incroyablement inefficace en termes d'utilisation des ressources. S'il y a beaucoup d'objets enfants inutiles qui sont inclus avec chaque requête parent, cela pourrait ralentir le code. – Southerneer

+0

Des nouvelles sur ce problème? Toujours en utilisant datamapper dans notre application et je voudrais un moyen de réduire le nombre de requêtes! – Brainfeeder

Questions connexes