2013-08-20 2 views
0

J'ai quelques entités apparentées, disons pour la commodité Product et Category. Ils sont liés OneToMany et ManyToOne. (chaque produit a une catégorie et une catégorie a beaucoup de produits)Quelle approche est la meilleure et la plus rapide - Symfony2, Doctrine2

Mon but est d'afficher dans un modèle toutes les catégories avec tous leurs produits, mais dans l'ordre alphabétique. Par exemple comme ceci:

Meubles

  • Lit
  • Canapé
  • TV

Repas

  • Banana
  • Poisson
  • Citron

Bureau

  • papier
  • Pen

Je veux les deux catégories et produits à trier.

Alors:

Approche 1

Écrire des requêtes avec la doctrine pour obtenir toutes les catégories nom OrderedBy ASC et pour obtenir tous les produits nom OrderedBy ASC puis dans le modèle:

{% for c in all_categories %} 

    {{ c.name }} 

    {% for p in all_products %} 
     {% if p.category == c %} 
      {{ p.name }} 
     {% endif %} 
    {% endfor %} 

{% endfor %} 

Approche 2

Obtenez uniquement le catégories, peu importe comment ils sont commandés. Changer chercher à impatient. Ensuite, écrivez un filtre de tri comme Brindille extension comme ceci:

public function sortByName($a, $b) 
{ 
     if($a->getName() === $b->getName()) { 
      return 0; 
     } 
     if($a->getName() < $b->getName()) { 
      return -1; 
     } 
     return 1;  
} 

et en utilisant un itérateur et uasort() avec cette fonction, puis dans le modèle:

{% for c in all_categories|sortbyname %} 

    {{ c.name }} 
    {% for p in c.products|sortbyname %} 
     {{ p.name }} 
    {% endfor %} 

{% endfor %} 

Ce que je peux voir est que dans Si la vérification est mauvaise, de nombreux contrôles seront redondants. Et obtenir tous les produits quand j'ai déjà toutes les catégories est également redondant. Mais je pense que le tri avec Doctrine devrait être plus rapide qu'avec l'extension twig. Donc, je ne peux pas dire lequel devrais-je utiliser. Si c'est important, dans mon cas, j'ai 3 entités, comme ceci: Chaque magasin a des catégories et chaque catégorie a des produits.

Pouvez-vous s'il vous plaît aidez-moi? Merci d'avance! :)

+0

une boucle if hein: P –

+0

: $ Je suppose que c'est venu car il y a une boucle for avant l'instruction if, et la boucle for est vraiment une boucle: D – Faery

+0

Je pense que pour ce que vous faites, une boucle imbriquée est acceptable .. si vous essayez juste de décider de quelle manière, approchez 1 est plus facile à lire. quel est le point d'utiliser une extension de brindille? –

Répondre

0

Ceci est plus un choix d'algo plutôt qu'un problème de symfony/doctrine.

Mon approche consiste à trier tous les produits par (nom de catégorie, nom de produit), puis de les parcourir pour les stocker dans un tableau indexé par votre catégorie. Il peut être utilisé si vous avez beaucoup de produits, et assez de mémoire pour charger tous les objets à un, mais sera plus rapide (#nbproducts, et non # nbproducts * # nbcategories), et utilisera une seule requête ORM, qui utilisera des index pour trier les données.

Code Php ressemblerait à ceci:

$sorted_products = array(); 
foreach ($products as $product) { 
    $category = $product->getCategory(); 
    if (!array_key_exists($category->getId(), $sorted_products)) { 
     $sorted_products[$category->getId()] = array('category' => $category, 'products' => array()); 
    } 
    $sorted_products['products'][] = $product; 
} 

Et puis il vous suffit de faire 2 foreach dans votre branche:

{% for category_infos in sorted_products %} 
    {{ category_infos.category.name }} 
    {% for product in category_infos.products %} 
    {{ product.name }} 
    {% endfor %} 
{% endfor %} 
Questions connexes