Reputation: 132
I have the entities Store, Owner and Town and i want to count all the stores that an owner has, categorized by their Town.
I have this Query in my Controller
$query = $this->getDoctrine()->getRepository('WebBundle:Store')
->createQueryBuilder('s')
->select('t.name, COUNT(s) as counter')
->groupBy('s.town')
->leftJoin('s.owner','o')
->leftJoin('s.town','t')
->where('s.owner = :id')
->orderBy('t.name','ASC')
->setParameter('id', $id)
->getQuery();
$list = $query->getResult();
Is there any way to select all columns from Town instead of declaring every column? Something like ->select('t.*, COUNT(s) as counter')
. I can select the ones i need now, but for larger tables I will need other method.
I've tried ->select('t, COUNT(s) as counter')
but I got an exception error.
For further information, in my twig template i want to show this:
{% for town in list %}
<span>{{ town.name }}</b> [{{ town.counter }}]</span>
{% endfor %}
Thanks for all in advice!
Upvotes: 4
Views: 24593
Reputation: 7617
You can select all by omitting the column name like or the match-all wild-card. So, instead of t.name or t.*, you can simply do t Like So:
$query = $this->getDoctrine()->getRepository('WebBundle:Store')
->createQueryBuilder('s')
->select('t, COUNT(s) AS counter')
->groupBy('s.town')
->leftJoin('s.owner','o')
->leftJoin('s.town','t')
->where('s.owner = :id')
->orderBy('t.name','ASC')
->setParameter('id', $id)
->getQuery();
$list = $query->getResult();
Upvotes: 2
Reputation: 1684
I guess you have some relations in your entities.
Owner
must have a 1-n relation with Store
.
So, your Owner
entity will be looks like this :
class Owner
{
protected $stores;
// ...
public function __construct()
{
$this->stores = new ArrayCollection();
}
public function getStores()
{
return $this->stores;
}
public function setStores($stores)
{
$this->stores = new ArrayCollection();
foreach ($stores as $store)
{
$this->stores->add($store);
}
return $this;
}
public function addStore(Store $store) // ... can use $this->store->add()
public function removeStore(Store $store) // ... can use $this->store->removeElement()
// etc ...
}
So now, you can use the Collection::count()
Doctrine method !
$storesCnt = $user->getStores()->count();
You want to get all stores for a user and a town ?
No problem ! Collection::filter()
is your friend !
$storesForAUserAndAGivenTown = $user->getStores()->filter(function (Store $store) use ($town) {
return ($store->getTown() === $town);
});
That's it.
Consider the first rule of Doctrine is Forget the database !
, so use DQL or QueryBuilder only and only if it's necessary.
Hope it will help you.
Upvotes: 3