Question

I'm trying to find a User's grocery items in a categorized list. The associations are Category hasMany Item hasMany User through Grocery. I'm using the Containable Behavior and it is not filtering out all other Grocery. It returns every item basically.

My controller function:

function showlist() {
$categories = $this->Category->find('all', array(
    'contain' => array(
        'Item' => array(
            'Grocery' => array(
                'conditions' => array(
                    'Grocery.user_id =' => $this->Auth->user('id')
                )
            )
        )
    )
));

Array that's returned:

Array
(
    [0] => Array
        (
            [Category] => Array
                (
                    [id] => 10
                    [parent_id] => 
                    [name] => Dairy
                    [lft] => 1
                    [rght] => 6
                )

            [Item] => Array
                (
                )

        )

[1] => Array
    (
        [Category] => Array
            (
                [id] => 11
                [parent_id] => 10
                [name] => Milk
                [lft] => 2
                [rght] => 3
            )

        **[Item] => Array
            (
            )**

    )

[2] => Array
    (
        [Category] => Array
            (
                [id] => 12
                [parent_id] => 10
                [name] => Cheese
                [lft] => 4
                [rght] => 5
            )

        [Item] => Array
            (
            )

    )

[3] => Array

I don't want to return any Item arrays that don't have a Grocery(ItemUser) below them.


This works but now it only displays flatly. I need it to show all items of one category in that nested array.

It's showing:

Array
(
[0] => Array
    (
        [Category] => Array **<--This could be the same category as**
            (...)

        [Item] => Array
            (...)

        [Grocery] => Array
            (...)
    )
[1] => Array
    (
        [Category] => Array **<--This**
            (...)

        [Item] => Array
            (...)

        [Grocery] => Array
            (...)
    )
[2]...

And I need it to be:

Array
(
[0] => Array
    (
        [Category] => Array 
            (...
            [Item] => Array
            (...)

            [Item] => Array
            (...)
            )
    )
[1] => Array
    (
        [Category] => Array
            (...)

        [Item] => Array
            (...)
    )
[2]...

Don't even really need the Grocery array, just have to search thru them for criteria.

Was it helpful?

Solution

You cannot limit your main Model's results based on conditions within the Contain. When you use contain(), it actually creates multiple queries - that keeps you from being able to limit based on contained conditions.

To resolve this, you need to use JOINs [ see CakePHP Joining Tables ] instead of contain.

OTHER TIPS

If you want nested formatting, could you move all this to another (e.g Groceries) controller which would allow you to limit by user_id or (but I have to admit that I'm not sure whether this is good Cake practice, although I have successfully used this approach...in 1.3 anyway) something along the lines of:

$groceries = $this->Category->Item->Grocery->find('all', array(
    'conditions' => array(
         Grocery.user_id =' => $this->Auth->user('id')
    )
));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top