iFeghali,

I have a somewhat similar problem. I have spent today an hour or two
looking into how Cake handles db queries for hasMany vs. hasOne or
belongsTo relationships. Hopefully this will help you to understand
why are you seeing what you are seeing.

Cake processes hasMany and hasOne, belongsTo differently. In the case
of hasOne and belongsTo, when, say, 2 models are involved, they
generate 1 query with a join, and then retrieve data in one shot.

In the case  when model A hasMany Model B (for example Machine and
MachineContact) it looks like cake will first retrieve a query for
Machine data and then for each machine there will be one query to
retrieve MachineContract.

So there are 2 logical branches and each calls afterFind slightly
different.

In the case of hasOne I see a call in the __filterResults() function
around line 716 of db_source.php like such ( I am using Cake 1.2.5):

                                                if (isset($model->{$className}) 
&& is_object($model->
{$className})) {
                                                        $data = 
$model->{$className}->afterFind(array(array($className
=> $results[$i][$className])), false);
                                                }

This will pass your afterFind method a structure $result[0]
['MachineContact'][..]


In the case of hasMany afterFind() is called in the queryAssociation()
function line 877 as follows:

                                        if 
(isset($resultSet[$i][$association])) {
                                                $resultSet[$i][$association] = 
$linkModel->afterFind($resultSet
[$i][$association]);
                                        }
and this passes $result[...] date to afterFind()


Is this a defect? I can not tell without deeper understanding of why
it was coded this way.




On Sep 2, 3:56 pm, iFeghali <[email protected]> wrote:
> anyone got a clue ?
>
> I am still very confused on this matter. I have tried moving from
> "recursive" to "containable" with no luck.
>
> Thank you.
>
> On Jul 28, 5:31 pm, iFeghali <[email protected]> wrote:
>
> > Hello All,
>
> > I found myself stuck for a week in an issue that I would really
> > appreciate any kind of help. Thats my scenario:
>
> > Machine HABTM Service
> > Machine belongsTo Type
> > Type hasOne Machine
> > Machine hasMany MachineContact
> > MachineContact belongsTo Machine
>
> > Now I have Machine->afterFind() hypothetically defined as:
>
> > <?php
> > functionafterFind($results, $primary = false) {
> > print_r($results);
> > return $results;}
>
> > ?>
>
> > Recursive is set to 2 for everything. So far so good.
>
> > If I go to /services/view/someId I get:
>
> > Array
> > (
> >     [0] => Array
> >         (
> >             machine attribs ...
> >             [MachinesService] => Array
> >                 (
> >                   ...
> >                 )
> >             [Type] => Array
> >                 (
> >                   ...
> >                 )
> >             [MachineContact] => Array
> >                 (
> >                     [0] => Array
> >                         (
> >                           ...
> >                         )
>
> >                     [1] => Array
> >                         (
> >                           ...
> >                         )
> >                 )
> >         )
> > )
> > Array
> > (
> >     [0] => Array
> >         (
> >             [Machine] => the Array above
> >        )
> > )
>
> > First question, I do not understand whyafterFind() was called twice.
> > In the SQL log there is only one query searching the machines table.
> > As I browsed cake's source I found thatafterFind() in called in the
> > model layer and after that again at the DB layer. Did I get it right ?
> > If so, why is the reason for that ?
>
> > But the real issue comes when I go to /types/view/someId:
>
> > Array
> > (
> >     [0] => Array
> >         (
> >             [Machine] => Array
> >                 (
> >                  ...
> >                 )
> >         )
> > )
> > Array
> > (
> >     [0] => Array
> >         (
> >             [Machine] => Array
> >                 (
> >                     [0] => Array
> >                         (
> >                            machine attribs...
> >                             [Type] => Array
> >                                 (
> >                                  ...
> >                                 )
> >                             [MachineContact] => Array
> >                                 (
> >                                     [0] => Array
> >                                         (
> >                                          ...
> >                                         )
> >                                 )
> >                             [Service] => Array
> >                                 (
> >                                     [0] => Array
> >                                         (
> >                                           ...
> >                                         )
> >                                 )
> >                         )
> >                 )
> >         )
> > )
>
> >afterFind() is called twice again as [un]expected. The problem is,
> > this time, in the first run it didn't fetch any of the Machines
> > associated models, even though recursive is set to 2. Also, the array
> > is indexed by model name what doesn't happens in the first test.
> > Secondly, in the second run the machine array comes complete with all
> > the attributes plus the associated models, indexed by model name
> > again.
>
> > So, what did I missed here ?
>
> > Thank you.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to