-1

I am following the doctrine documentation about sort association: Ordering To-Many Associations

I have a category entity, it has many articles:

class Category
{
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Article", mappedBy="category")
     * @ORM\OrderBy({"position"="ASC"})
     */
    private $articles;

}

article entity has a position field for sort:

class Article
{
    /**
     * @Gedmo\SortablePosition
     * @ORM\Column(name="position", type="integer", nullable=true)
     */
    private $position;
}

and get data from controller:

   /**
   * @Route("/zen", name="zen")
   */
  public function zen(){
    $category = $this->getDoctrine()->getRepository(Category::class);
    $categories = $category->createQueryBuilder('c')
      ->innerJoin('c.articles', 'a')
      ->addSelect('a')
      ->getQuery()->getResult();

    return $this->render('index/zen.html.twig', [
      'categories' => $categories
    ]);
  }

notice above, I add inner join and addSelect for avoid N+1 query problem.

in the template:

{% for c in categories %}
    {% for a in c.articles %}
      position: {{a.position}}, id: {{a.id}}
    {% endfor %}
{% endfor %}

the result should be ordered by position, like:

position: 1, id: 2
position: 2, id: 1
position: 3, id: 3
position: 4, id: 4

but actually ordered by id:

position: 2, id: 1
position: 1, id: 2
position: 3, id: 3
position: 4, id: 4
msg
  • 7,863
  • 3
  • 14
  • 33
Moon soon
  • 2,616
  • 2
  • 30
  • 51

1 Answers1

1

The Sortable behavior, when enabled, will attach a listener to the entity to update the SortablePosition property of all entries when one is updated, but will not affect query behavior.

You have to add the ordering to the query yourself or use the repository provided by the behavior by declaring it in your class:

/**
 * @ORM\Entity(repositoryClass="Gedmo\Sortable\Entity\Repository\SortableRepository")
 */
class Article
{
    /**
     * @Gedmo\SortablePosition
     * @ORM\Column(name="position", type="integer", nullable=true)
     */
    private $position;
}

Then you can get a queryBuilder with the predefined order via the repository (the entity will recieve the alias n):

$categories = $category->getBySortableGroupsQueryBuilder()->innerJoin('n.articles', 'a');
msg
  • 7,863
  • 3
  • 14
  • 33
  • thanks for your reply, your solution is works, I got, it should be sql problem, I just add more order statement to order results will be fine, like: `->orderBy('c.position', 'ASC')->addOrderBy('a.position', 'ASC') ` – Moon soon Aug 19 '19 at 01:25