문제

I'm trying to return a list of events, and include the city where it's taking place. The city is only associated through the Event's Venue though.

Below is the code I'm using. It returns all the correct data, but it doesn't return ANY city data (other than the city_id field in Venue - which I'm not sure why it's returning).

Associations:

Event belongsTo Venue
Venue hasMany Event

Venue belongsTo City    
City hasMany Venue

Code:

        $this->Event->Behaviors->attach('Containable');
        $events = $this->Event->find('all', array(
            'limit' => 5,
            'order' => 'Event.created DESC',
            'fields' => array(
                'name',
                'description',
                'phone',
                'price_general',
                'price_child',
                'price_adult',
                'price_child',
                'tickets_url'
            ),
            'contain' => array(
                'Venue' => array(
                    'fields' => array(
                        'name',
                        'address',
                        'city_id',
                    ),
                    'City' => array(
                        'fields' => array(
                            'City.name',
                            'state'
                        ),
                        'conditions' => array(
                            'City.id' => 'Venue.city_id'
                        )
                    )
                ),
                'Schedule' => array(
                    'fields'=>array(),
                    'Date' => array(
                        'conditions'=>array(
                            'Date.start >=' => $start_date,
                            'Date.start <=' => $end_date,
                        )
                    )
                )
            ),
        ));

Bonus answer: (that I have currently asked in another StackOverflow question) - The Date conditions are supposed to filter which events show up, but instead, they're only filtering which Date data to show.


WORKING ANSWER: (thanks bancer)

    $this->Event->recursive = -1;
    $options['joins'] = array(
            array('table' => 'schedules',
                'alias' => 'Schedule',
                'type' => 'LEFT',
                'conditions' => array(
                    'Event.id = Schedule.event_id',
                )
            ),
            array('table' => 'dates',
                'alias' => 'Date',
                'type' => 'LEFT',
                'conditions' => array(
                    'Date.schedule_id = Schedule.id',
                )
            )
        );
        $options['fields'] = array(
            'Event.name',
            'Schedule.start_date',
            'Date.start',
        );
        $options['limit'] = 5;
        $events = $this->Event->find('all', $options);
도움이 되었습니까?

해결책

I would recommend to avoid using Containable. It generates too many queries in some cases. A better way for complex queries is to join tables "manually".

Another option I would consider at the first place is to search through 'Venue' model without using Containable like this: $this->Event->Venues->find('all', ...). As Venues directly associated with Cities and Events there should be possible to get what you want without extra complexities.

Update: take a look at the question How to change the sequence of 'joins' in CakePHP?

다른 팁

instead of containable, did you try including the city data in fields itself by fields=> array('','','City.name)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top