tags:

views:

190

answers:

2

I was looking at examples on the CakePHP website, in particular hasOne used in linking models. http://book.cakephp.org/view/78/Associations-Linking-Models-Together

My question is this, is CakePHP using two queries to build the array structure of data returned in a model that uses hasOne linkage?

Taken from CakePHP: //Sample results from a $this->User->find() call.

Array
(
    [User] => Array
        (
            [id] => 121
            [name] => Gwoo the Kungwoo
            [created] => 2007-05-01 10:31:01
        )
    [Profile] => Array
        (
            [id] => 12
            [user_id] => 121
            [skill] => Baking Cakes
            [created] => 2007-05-01 10:31:01
        )
)

Hope this all makes sense.

A: 

pretty sure most if not all hasOne and belongsTo are done using join. so one query. you can always set debug to 2 in config.php to see the sql query

Funky Dude
What then of the array structure, can I assume they are indeed using one query, but then iterating over the SQL result set to form this structure?
Andre
yes you can assume that.
Funky Dude
+2  A: 

Model::find uses joins to retrieve model records associated to the source model by hasOne and belongsTo relationships. The specific SQL queries look something like (using a Car belongsTo Driver model structure):

SELECT `Car`.`brand`, `Car`.`colour`, `Driver`.`name`, `Driver`.`age`
    FROM `cars` AS `Car`
    LEFT JOIN `drivers` AS `Driver` ON `Car`.`id` = `Driver`.`car_id`
WHERE `Car`.`brand` = 'Aston Martin'

The fields belonging to each model can be parsed out into corresponding array elements by the table/model alias:

  • Car.brand becomes $result['Car']['brand']
  • Car.colour becomes $result['Car']['colour']
  • Driver.name becomes $result['Driver']['name']
  • Driver.age becomes $result['Driver']['age']

Only one query required.

Retrieving data for hasMany and hasAndBelongsToMany associations requires additional queries, sometimes many more.

Daniel Wright
Understood.In the event that find() is used to return all (multiple) users, is the SQL result set iterated over to create an enumerated array containing corresponding array with table/model alias?In which case does this not add an extra loop?
Andre
Yes, in that scenario, it will loop through every row returned by the query, and through each field of every row, to prepare the array ultimately returned by `Model::find('all')`. You can dig into the documentation for `DboSource::fetchAll` and `DboMysql::fetchResult` (or whatever data-source interests you) for specific details.
Daniel Wright
I imagine this may be tough question to answer, but does the extra loop not add a certain amount of inefficiency especially when working with models that have many 'hasMany' and 'hasOne' associations?Thanks again for all the help.
Andre