views:

175

answers:

2

Hi, I am relatively new to CakePHP, I am doing fine with the documentation, but I've been trying to find a way out to this problem for weeks and I don't seem to find the solution, I am sure it is easy and maybe even automagicaly doable, but I just don't know how to find it (maybe I don't know the jargon for these kind of things)

My model structure is like this:

<?php
    class Trip extends AppModel {
          var $belongsTo = array(
            'User' => array(
                'className' => 'User',
                'foreignKey' => 'user_id'
            ),
            'Start' => array(
                'className' => 'Place',
                'foreignKey' => 'start_id'
            ),
            'End' => array(
                'className' => 'Place',
                'foreignKey' => 'end_id'
            ),
            'Transport' => array(
                'className' => 'Transport',
                'foreignKey' => 'transport_id'
            )
        );

     }
?>

<?php
class Place extends AppModel {

    var $belongsTo = array(
        'User' => array(
            'className' => 'User',
            'foreignKey' => 'user_id'
        ),
        'Country' => array(
            'className' => 'Country',
            'foreignKey' => 'country_id'
        ),
        'State' => array(
            'className' => 'State',
            'foreignKey' => 'state_id'
        ),
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id'
        )
    );
    var $hasMany = array(
        'PlaceStart' => array(
            'className' => 'trip',
            'foreignKey' => 'start_id',
            'dependent' => false
        ),
        'PlaceEnd' => array(
            'className' => 'trip',
            'foreignKey' => 'end_id',
            'dependent' => false
        )
    );

}
?>

<?php
class State extends AppModel {

    var $belongsTo = array(
        'Country' => array(
            'className' => 'Country',
            'foreignKey' => 'country_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );

    var $hasMany = array(
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id',
            'dependent' => false
        )
    );

}
?>

... and so forth with User, City, Country, and Transport Models.

What I am trying to achieve is to get all the information of the whole tree when I search for a Trip.

<?php
class TripController extends AppController {
    function index() {
        debug($this->Trip->find('first'));
    }
}

Outputs

Array
(
    [Trip] => Array
        (
            [id] => 6
            [created] => 2010-05-04 00:23:59
            [user_id] => 4
            [start_id] => 2
            [end_id] => 1
            [title] => My trip
            [transport_id] => 1
        )

    [User] => Array
        (
            [id] => 4
            [name] => John Doe
            [email] => [email protected]
        )

    [Start] => Array
        (
            [id] => 2
            [user_id] => 4
            [country_id] => 1
            [state_id] => 1
            [city_id] => 1
            [direccion] => Lincoln Street
        )

    [End] => Array
        (
            [id] => 1
            [user_id] => 4
            [country_id] => 1
            [state_id] => 1
            [city_id] => 4
            [address] => Fifth Avenue
        )

    [Transport] => Array
        (
            [id] => 1
            [name] => car
        )
)

Here is the question: How do I get in one query all the information down the tree?

I would like to have something like

Array
(
    [Trip] => Array
        (
            [id] => 6
            [created] => 2010-05-04 00:23:59
            [User] => Array
                (
                    [id] => 4
                    [name] => John Doe
                    [email] => [email protected]
                )
            [Start] => Array
                (
                    [id] => 2
                    [user_id] => 4
                    [Country] => Array
                        (
                            [id] => 1
                            [name] = Spain
                        )
                    [State] => Array
                        (
                            [id] => 1
                            [name] = Barcelona
                        )
                    [City] => Array
                        (
                            [id] => 1
                            [name] = La Floresta
                        )
                    [address] => Lincoln Street
                )
            [End] => (same as Start)
            [title] => My trip
            [Transport] => Array
                (
                    [id] => 1
                    [name] => car
                )
        )
)

Can CakePHP create this kind of data? Not only for $this->Model->find() but also for $this->paginate() as for example:

    // filter by start
    if(isset($this->passedArgs['start'])) {
        //debug('isset '.$this->passedArgs['start']);
        $start = $this->passedArgs['start'];
        $this->paginate['conditions'][] = array(
            'OR' => array(
                'Start.address LIKE' => "%$start%",
                'Start.State.name LIKE' => "%$start%",
                'Start.City.name LIKE' => "%$start%",
                'Start.Country.name LIKE' => "%$start%"
            )
        );
        $this->data['Search']['start'] = $start;
    }

It seems like a rough question but I am sure this is extensively done and documented, I'd really appreciate any help. Thanks

Cheers

Naoise

+1  A: 

You seem to have everything setup OK. All you should have to do is set the recursive to 2 and that should give you an extra level to your data (assuming that you have set up all the relations correctly)

var $recursive =2;
paullb
Or `$this->Trip->find('first', array('recursive' => 2));`
bancer
Simply beautiful. Thanks a milion paullb and bancer!
Naoise Golden
+2  A: 

An alternative, more surgical, solution that's particularly useful if you need to go deeper than 2 levels or if you have a lot of 2nd level associations that you don't need for this particular problem is the Containable Behavior. This is the 1.2.x documentation. If you're using v1.3.x, you'll find it here.

Rob Wilkerson
thanks Rob. I appreciate you took the time
Naoise Golden