27

In Rails (and even in Doctrine < 2, IIRC) you can specify a default order for any model. For example, if you tell Rails to always order your customer table by name, Customer.all will always a list of customers ordered by name. It makes an enormous amount of sense.

From what I gather it's not possible to do this in Doctrine 2. Evidently they want you to create a query instead.

It would be a very DRY, logical and convenient feature to include, and an outstandingly stupid feature to choose to leave out, it seems to me.

I sincerely hope I'm wrong about this option not existing, and before I cry myself to sleep tonight, I wanted to check to see if maybe Doctrine does actually have a way to specify a default order and I just haven't been able to find it. Can anyone enlighten me?

Tom
  • 3,031
  • 1
  • 25
  • 33
Jason Swett
  • 43,526
  • 67
  • 220
  • 351

6 Answers6

45

Whilst you don't seem to be able to do this for an entire model ala Doctrine 1, you can specify ordering as a notation on the inverse side of a relation:

// Entity/Category

/**
 * @var ArrayCollection $posts
 *
 * @ORM\OneToMany(targetEntity="Post", mappedBy="category")
 * @ORM\OrderBy({"name" = "ASC"})
 */
private $posts;

Also, if you're implementing entity manager services such as those in SonataNewsBundle, you can specify defaults via optional arguments i.e.

class PostManager extends ModelPostManager
{

    /**
     * {@inheritDoc}
     */
    public function findBy(array $criteria, array $orderBy = array('name' => 'asc'))
    {
        return $this->em->getRepository($this->class)->findBy($criteria, $orderBy);
    }
}
Steve
  • 5,771
  • 4
  • 34
  • 49
27
$items = $entityManager()->getRepository('Item')->findBy(array(),array('field_to_sort_on'));

And of course you can just add a method to the Item repository

public function findAllWithDefaultSort()
{
    return $this->findBy(array(),array('default_field_to_sort_on'));
}

No real need to make a query in this case. Keep in mind that D2 focuses on object models with relations. There are a gazillion active record based alternatives out there.

To answer your question: No.

Cerad
  • 48,157
  • 8
  • 90
  • 92
  • Nice - the extra `findBy()` parameter is helpful to know about. Thanks. Unfortunately it's not the same thing as a default order. Neither of these workarounds are nearly as DRY as it would be just to have a default order. – Jason Swett Apr 02 '12 at 19:57
  • 15
    With this method in Symfony 2.1 I get Unrecognised field: 0 with `->findBy(array(),array('field_to_sort_on'))`. To fix this it needs the field as the array key and the direction as the array value: `->findBy(array(),array('field_to_sort_on' => 'ASC'))` – Luke Jan 15 '13 at 11:59
  • Symfony 2.3.2 doesn't seem to allow functions that start with `findAll...` in repositories (`Undefined method 'findAllWithDefaultSort'. The method name must start with either findBy or findOneBy!`) – Gottlieb Notschnabel Aug 16 '13 at 16:13
  • @GottliebNotschnabel true, but I believe he said to "add a method to the item repository" which would mean that his function "findAllWithDefaultSort" would be a custom function and not a magic function as you're talking about. – mason81 Mar 25 '14 at 16:31
  • @mason81 Yeah, you're right. I missed that. My bad. – Gottlieb Notschnabel Mar 26 '14 at 13:56
  • @GottliebNotschnabel no worries. :) – mason81 Mar 27 '14 at 14:43
24

I had the same question, I found that overriding the findAll() function in your Repository works pretty well:

public function findAll()
{
    return $this->findBy(array(), array('lft'=>'asc'));  
}
10

A relatively simple way to achieve this is to override the findBy method in the Entity's repository class:

class MyEntityRepository extends EntityRepository
{
    /**
     * @inheritdoc
     */
    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $orderBy = $orderBy === null ? array('added' => 'desc') : $orderBy;
        return parent::findBy($criteria, $orderBy, $limit, $offset);
    }
}

This adds a default ordering to all the findBy methods, and allows you to override the ordering if you need to. The same can be done for findOneBy if needed.

Jrgns
  • 24,699
  • 18
  • 71
  • 77
6

It looks like no, there is no way to specify a default order in Doctrine 2.

Jason Swett
  • 43,526
  • 67
  • 220
  • 351
2

findBy's parameter 1 is the search criteria, parameter 2 is orderby and seems to need to take either ASC (ascending) or DESC (descending)

$accounts = $this->em->getRepository('Entities\User')
                     ->findBy(array('active' => 1), array('email' => 'ASC'));
Kijewski
  • 25,517
  • 12
  • 101
  • 143
timhc22
  • 7,213
  • 8
  • 48
  • 66