navige
navige

Reputation: 2517

CakePHP Containable showing wrong data

I have been looking around for a long time regarding the CakePHP containable, and somehow I get the impression there is a mistake in the CakePHP code... Let me give you the following example

Assume a Model "Accounting" that is related to "Instructions".

public $belongsTo = array('Instruction');

I do a join like this:

$options['contain'] = array(
        'Instruction' => array(
           'fields'  => array('Instruction.id', 'Instruction.main_student_id', 'Instruction.teacher_id'),
           'Student' => array(
               'fields' => array('Student.id', 'Student.full_name', 'Student.invoice_payer_id'),
           ),
           'Teacher' => array(
                'fields' => array('Teacher.id', 'Teacher.full_name'),
                'conditions' => array('Teacher.id' => $teacher_id)
           ),
        )
);      
return parent::find('all', $options);

So there is an instruction and to this instruction a student and a teacher belong to. I call find from the "Accounting" model

What I expect

  1. the joins are done automatically and correct
  2. the fields mentioned in the contain are retrieved

What I get

  1. the fields are joined, but wrongly; so the result array contains an Instruction with a Student and a Teacher. But instead of displaying the correct Teacher belonging to an Instruction, it always displays the one specified in the condition.

Example:

But let's go a step further:

  1. if $recursive = -1 is set then I only get returned only the fields of the model "Accounting"; the fields of Instruction, Student, Teacher are not retrieved

Let's make sure

So, what?

Could you please try to help me to understand... - why the joins are done wrongly? - why not all the fields are retrieved?

I tried already

Upvotes: 1

Views: 468

Answers (1)

pleasedontbelong
pleasedontbelong

Reputation: 20102

Containable also goes a step deeper: you can filter the data of the associated models.

http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html#containing-deeper-associations

The conditions you give on the containable are used as filters and not as restrictions for the joins. So it will not return the Instructions of a certain Teacher, but return all Instructions with their associated Teachers filtering the teachers with the condition array('Teacher.id' => $teacher_id)

Try adding the condition on the Instruction instead of the Teacher. Something like:

'Instruction' => array(
    'Student','Teacher',
    'conditions' => array('Instruction.teacher_id' => $teacher_id)

and this will return ALL the Accounting and it will filter only the Instructions of a certain teacher.

You could always do the join manually (It migth not look good but it works), just remember to set containable to false if you are doing it.

Hope this helps

Upvotes: 1

Related Questions