Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filter HABTM-associated model with conditions

preamble: a few days ago I asked a question to solve a HABTM-filter, I'm not able to do it even with tutorials, so "Obi Kwan Kenobi youre my only hope".

What I want to achieve: Filtering Staff by GroupID which is used in StaffStaffgroup

I'm having the following tablelayout

  • staffs (a person can belong to many groups)
  • staff_staffgroups (HABTM-linking table)
  • staffgroups (has a groupname)

The variable $tmp gets me a working array, but the problem is that Staff is a child object of StaffStaffgroups. I could parse throu and reassemble a array, but this isnt a nice solution. So I want to use the condition on Staff (see comented line) but then I get the error 1054 "column not found: 1054 Unknown column". I tried to bind and unbind, but no result there.

$group_id = 2;
$tmp = $this->Staff->StaffStaffgroup->find('all',
        array('conditions' => array(
            'StaffStaffgroup.staffgroup_id' => $group_id,
            'Staff.isActive =' => "1",
            'Staff.last_name LIKE' => "%$name%",
            )
         )
);

debug($tmp);

//$tmpConditions['AND'][] = array('StaffStaffgroup.staffgroup_id' => $group_ids);

EDIT:

I tried it with conditions and containable behaviour, but unfortunatelly its not filtering anything at all

    $this->Staff->contain(array('StaffStaffgroup'));
    $this->paginate = array('StaffStaffgroup' =>array(
                                    array('conditions'  => array(
                                            'StaffStaffgroup.staffgroup_id' => '2'
                                        )
                                    )
                                )
    );
  • I added to all models: public $actsAs = array('Containable');
  • I tried also with an inner join but no filtering there:

     $this->paginate = array( 
     'conditions' => array('StaffStaffgroup.staffgroup_id' => 2 ),
     'joins' => array(
        array(
            'alias' => 'StaffStaffgroup',
            'table' => 'staff_staffgroups',
            'type' => 'INNER',
            'conditions' => 'StaffGroup_id = StaffStaffgroup.staffgroup_id'
        )
     )
    

    );

like image 817
endo.anaconda Avatar asked Feb 04 '13 16:02

endo.anaconda


3 Answers

You cannot use the Containable behavior for this. Checkout the sql dump, you will see that the query is done.

I would do it in two steps

From StaffStaffgroup get the staff ids that belongs to the group you want

$staff_ids = $this->Staff->StaffStaffgroup->find(
    'all', 
    array(
        'conditions' => array('StaffStaffgroup.staffgroup_id' => $group_id, ),
        'recursive' => -1,
        'fields' => array('StaffStaffgroup.staff_id'),
    )
);

Then get all staff using the previous result

$staffs = $this->Staff->find(
    'all', 
    array(
        'conditions' => array(
            'Staff.id' => $staff_ids, 
            'Staff.isActive =' => "1",
            'Staff.last_name LIKE' => "%$name%",
        ),
    )
);
like image 176
kaklon Avatar answered Jan 01 '23 11:01

kaklon


You should look into the Containable behaviour.

http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html

This will allow you to query your Staff model and contain your StaffStaffgroup model, giving you the array organised in the way you want.

like image 20
David Yell Avatar answered Jan 01 '23 13:01

David Yell


I realize this question was asked a long time ago but my comment could still help someone else finding this post.

I created a behavior that creates the proper joins to the HABTM association behind the scenes making you able to use conditions on the HABTM-model.

Example

The model:

<?php
class Product extends AppModel {

    public $actsAs = array(
        'FilterHabtm.FilterHabtm',
        'Containable' // If you use containable it's very important to load it AFTER FilterHabtm
    );

    public $hasAndBelongsToMany = array(
        'Category' => array(
            'className' => 'Category',
            'foreignKey' => 'product_id',
            'associationForeignKey' => 'category_id',
            'with' => 'CategoryProduct'
        )
    );

}

The controller:

(The following is made possible by the behavior)

<?php
class ProductsController extends AppController {

    public $name = 'Products';

    public function index($categoryId = null) {
        $products = $this->Product->find('all', array(
            'conditions' => array(
                'Category.id' => $categoryId // Filter by HABTM conditions
            )
        ));
    }

}

Please see this url for download and complete usage instructions: https://github.com/biesbjerg/FilterHabtm

like image 45
Kim Biesbjerg Avatar answered Jan 01 '23 11:01

Kim Biesbjerg