Symfony doctrine : retrieve all parents on tree-like structure in one query

Asked
Active3 hr before
Viewed126 times

7 Answers

symfonyretrieve
90%

In my project I have severall entities which adopt a tree-like structure. On some entities I have implemented doctrine nested set behaviour and I have a clear parent-child structure. On others I defined my self a self-association as I have extra fields in the many to many table. For instance:,How can I prevent that and retrive the wole tree in one query? I know I can make a self join on subrecipes but how to repeat this as many times as needed to get the full tree?, Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers , Reconnecting with a previous professor then asking right away for a reference letter

Entity Recipe has $subrecipes SubRecipe is a new entity with a parameter called weight. SubRecipe $parentRecipe is the parent Recipe. SubRecipe $subRecipe is the child Recipe :

/**
 * @ORM\OneToOne(targetEntity="\AppBundle\Entity\FoodAnalytics\Recipe", inversedBy="parentRecipe")
 * @ORM\JoinColumn(name="subrecipeId", referencedColumnName="id", nullable=false)
 */
private $subRecipe;

/**
 * @ORM\ManyToOne(targetEntity="\AppBundle\Entity\FoodAnalytics\Recipe", inversedBy="subrecipes")
 * @ORM\JoinColumn(name="parentRecipeId", referencedColumnName="id", nullable=false, onDelete="cascade")
 */
private $parentRecipe;
load more v
88%

In a hierarchical data model, data is organized into a tree-like structure. The tree structure allows repeating information using parent/child relationships. For an explanation of the tree data structure, see here.,There are three major approaches to managing tree structures in relational databases, these are:,There it is, the tree with all the related data you need, all in one query.,Getting Relation Information

Here is the same example in YAML format. You can read more about YAML in the YAML Schema Files chapter:

1-- -
# schema.yml

#...
   Category:
   actAs: [NestedSet]
columns:
   name: string(255)
2
3
4
5
6
7
8
load more v
72%

Also checkout vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity/Repository/NestedTreeRepository.php.,Tree – Nestedset behavior extension for Doctrine 2,StofDoctrineExtensionsBundle,The tree extension needs its own entity to do the work . Its mapping needs to be registered in Doctrine.

Retrieve the full tree (or subtree)

Retrieve “Bikes” category and all its subcategories using repository method childrenHierarchy . childrenHierarchy can return categories (and subcategories) as a array tree or formatted HTML string. For example nested ul and li.

childrenHierarchy
load more v
65%

In the Doctrine Extensions Tree, it’s impossible to swap root elements using standard methods (moveUp, moveDown). If you try to do it, then the exception with the appropriate message "climbs" out.,Removal of the descendants Nested Tree produces automatically. There's nothing to configure.,These patterns are connected in the method of the class configureListFields PageAdmin.,There is a feature in construction of the tree in the Nested tree. For the correct sequence of going through the tree from left to right, it is necessary to sort the items first by the field, root, and then by the field lft. To do this, there was added property $ datagridValues.

class Page {
   ...
   public
   function __toString() {
      $prefix = "";
      for ($i = 2; $i <= $this - > lvl; $i++) {
         $prefix. = "& nbsp;& nbsp;& nbsp;& nbsp;";
      }
      return $prefix.$this - > title;
   }

   public
   function getLaveledTitle() {
      return (string) $this;
   }
   ...
}
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field %}

    {% spaceless %}
        {% if object.parent.children[0].id != object.id %}
            <a href="{{ path('page_tree_up', {'page_id': object.id}) }}">

            </a>
        {% endif %}
    {% endspaceless %}
{% endblock %}
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field %}

    {% spaceless %}
        {% if object.parent.children[object.parent.children|length - 1].id != object.id %}
            <a href="{{ path('page_tree_down', {'page_id': object.id}) }}">
            </a>
        {% endif %}
    {% endspaceless %}
{% endblock %} 
page_tree_up:
   pattern: /admin/page_tree_up / {
      page_id
   }
defaults: {
   _controller: ShtumiPravBundle: PageTreeSort: up
}

page_tree_down:
   pattern: /admin/page_tree_down / {
      page_id
   }
defaults: {
   _controller: ShtumiPravBundle: PageTreeSort: down
}
getDoctrine() - > getEntityManager();
$repo = $em - > getRepository('ShtumiPravBundle:Page');
$page = $repo - > findOneById($page_id);
if ($page - > getParent()) {
   $repo - > moveUp($page);
}
return $this - > redirect($this - > getRequest() - > headers - > get('referer'));
}

/**
 * @Secure(roles="ROLE_SUPER_ADMIN")
 */
public
function downAction($page_id) {
   $em = $this - > getDoctrine() - > getEntityManager();
   $repo = $em - > getRepository('ShtumiPravBundle:Page');
   $page = $repo - > findOneById($page_id);
   if ($page - > getParent()) {
      $repo - > moveDown($page);
   }
   return $this - > redirect($this - > getRequest() - > headers - > get('referer'));
}
}
class Page {
   ...
   /**
    * @ORM\OneToMany(targetEntity="Service", mappedBy="
    page", cascade={"all"}, orphanRemoval=true)
    * @ORM\OrderBy({"position"="ASC"})
    */
   protected $services;
   ...
}
load more v
75%

To find all posts by an author with a given name, the best approach would be to find a user with its name and request all users’ posts:,Like the Symfony YAML file, this one for Laravel is also human readable and looks clean. You can additionally create .env.testing file that will be used when running PHPUnit tests.,There’s no clear winner between Laravel and Symfony, as everything depends on your final goal.,However, you may feel more comfortable with the default PHP configuration syntax Laravel is using and you don’t have to learn YAML syntax.

Symfony installation is as simple as the following:

# Downloading Symfony installer
sudo curl - LsS https: //symfony.com/installer -o /usr/local/bin/symfony
   # Granting permissions to execute installer
sudo chmod a + x / usr / local / bin / symfony
# Creating new Symfony project
symfony new symfony_project
# Launching built - in server
cd symfony_project / && php bin / console server: start
load more v
40%

The Serializer component provides several built-in encoders:,All these encoders are enabled by default when using the Serializer component in a Symfony application.,The AbstractNormalizer::OBJECT_TO_POPULATE is only used for the top level object. If that object is the root of a tree structure, all child elements that exist in the normalized data will be re-created with new instances.,To use the Serializer component, set up the Serializer specifying which encoders and normalizer are going to be available:

1
$ composer require symfony / serializer
load more v
22%

Can't we lazyload that somehow? I'm curious about that as additional queries to load an entity are probably problematic.,That generic hierarchy framework will apply to every tree-like structure in Drupal (taxonomy terms, menu links, books), and the basic API that I have in mind for it is to have the methods that interact with the tree at the field item list level, not at the entity level., #2942358: The taxonomy_term_hierarchy table will be removed in Drupal core 8.6.0 ,#2942358: The taxonomy_term_hierarchy table will be removed in Drupal core 8.6.0

Let's look at the following code:

$term = Term::load(12);
$term - > parent - > target_id // returns always NULL, even if the term has a parent
load more v

Other "symfony-retrieve" queries related to "Symfony doctrine : retrieve all parents on tree-like structure in one query"