简体   繁体   中英

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?

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();
}

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM