Apfelsaft
Apfelsaft

Reputation: 5846

Symfony2: Adding a join condition to a ManyToMany relationship

I have to change something in an existing Symfony2 project, but unfortunately I have never worked with Symfony2 before.

The database contains the following tables:

Location
========
id 
....

Deal
========
id 
deleted
...

deal_location
=================
deal 
location 

There is a Many-To-Many relationship between Deal and Location. This is mapped in the Location.orm.yml file like this:

 manyToMany:
    deals:
        cascade: ['all']
        targetEntity: Deal
        mappedBy: locations

What I want to do is to exclude all deals which where deleted (deleted = 1) when reading the locations from the Database.

As I found out, this can be done in de LocationRepository class. In that class, I found the following function:

    public function getFindAllByLatLonQueryBuilder($lat, $lon)
{

    $qb = $this->createQueryBuilder('l');
    $qb
        ->where('l.deleted IS NULL OR l.deleted = false')
        ->orderBy('(((ACOS(SIN((:lat*PI()/180)) *
        SIN((l.latitude*PI()/180))+COS((:lat*PI()/180)) *
        COS((l.latitude*PI()/180)) * COS(((:lon-l.longitude)*
        PI()/180))))*180/PI())*60*1.1515*1.609344)', 'ASC')
        ->setParameter('lat', $lat)
        ->setParameter('lon', $lon)
    ;

    return $qb->getQuery()->getResult();
}

I found a similar question and added the following line:

 ->leftJoin('l.deals', 'deals', 'WITH', 'deals.deleted = 0')

Unfortunately this doesn't work. How can I make this work?

Upvotes: 2

Views: 98

Answers (3)

tftd
tftd

Reputation: 17032

Instead of having two conditions in your where clause I would leave only where('l.deleted IS NOT true AND deals.deleted IS NOT true') and would simply add the leftJoin clause.

Something like this should do the work:

public function getFindAllByLatLonQueryBuilder($lat, $lon)
{
    $qb = $this->createQueryBuilder('l')
        ->leftJoin('l.deal', 'deal', 'WITH', 'deal.deleted IS NOT true') // you can also try 'deal.deleted != true'
        ->where('l.deleted IS NOT true')
        ->orderBy('(((ACOS(SIN((:lat*PI()/180)) *
        SIN((l.latitude*PI()/180))+COS((:lat*PI()/180)) *
        COS((l.latitude*PI()/180)) * COS(((:lon-l.longitude)*
        PI()/180))))*180/PI())*60*1.1515*1.609344)', 'ASC')
        ->setParameter('lat', $lat)
        ->setParameter('lon', $lon)
    ;
    return $qb->getQuery()->getResult();
}

Upvotes: 2

Sędziwój
Sędziwój

Reputation: 66

leftJoin() not help u, is only needed if u use data from it in query, it not exclude deals, because u in this query get only localization. I think exclude localization with deleted deals not help to, because in some localization u will have deleted and not deals. It must be in other part of code where u get deals for localizations. So u must first find where deals are get from db, to make it only take not deleted.

Upvotes: -1

LBA
LBA

Reputation: 4089

try

->leftJoin('l.deals', 'deal', 'WITH', 'deal.deleted = 0')

you always have to join the object's name which in your case seems to be deals instead of deal given your yml.

Another thing which makes me wonder is why for location they check on deleted = null or false (see your code) but you check against deleted = 0. Are you sure this is the right check?

Upvotes: 0

Related Questions