5

Is it possible to define global conditions for Model ?

I have 2 Models: User and Student. In database both of them are using table users but each student has set parent_id to its owner (which is set in the same table) while each user has parent_id set to Null.

When I use for example

$this->find('all'); 

in Student Model I want to force Cake to return only those records from database table users where parent_id != Null .

So the question is - can I define somehow global conditions in the Model? Something like that:

public $conditions = array('Student.parent_id !=' => Null);

Ziemo
  • 941
  • 8
  • 27
  • Possible duplicate of [How to define "global" find conditions for model in CakePHP?](http://stackoverflow.com/questions/6772737/how-to-define-global-find-conditions-for-model-in-cakephp) – AD7six Jun 07 '16 at 08:57

2 Answers2

6

Use beforeFind

You can use before find to modify all queries issued for a model:

function beforeFind(array $queryData) {
    $queryData['conditions'][]['NOT'][$this->alias . '.parent_id'] = null;
    return $queryData;
}

Be careful using this technique to not overwrite existing conditions (note the extra []) otherwise a query for "not parent_id 2" becomes "not parent_id null".

Community
  • 1
  • 1
AD7six
  • 63,116
  • 12
  • 91
  • 123
  • There might be a problem in situations when you need to be able to disable the global conditions from time to time. With `beforeFind()` you'd have to plase an `isset()` applying the global condition only if no manual is present, but it can get tricky if the manual condition is something like `array('User.is_banned LIKE'=>'%')`. [Here's why I'm using the `'%'` thing](http://stackoverflow.com/a/3430749/722036) – ᴍᴇʜᴏᴠ Jun 06 '16 at 20:08
  • @TheSexiestManinJamaica very true, which is why it's better to use a behavior rather than embed code directly in a model. Don't know what you mean about `array('User.is_banned LIKE'=>'%')` you should never need to create a condition like that. – AD7six Jun 06 '16 at 21:10
0

you could use the afterFind callback to alter your finds in the model

public function afterFind($results, $primary = false) {
    foreach ($results as $key => $val) {
        if ($val['parent_id'] == NULL) { //no parent_id set then remove that part of the results
           unset($results[$key]);
        }
    }
    return $results;
}

reference: http://book.cakephp.org/2.0/en/models/callback-methods.html

Alex Stallen
  • 2,223
  • 15
  • 17
  • afterFind is a useful callback, but it's not appropriate for the example in the question. Consider having many users, only a few students and a query with a limit - it's quite possible to return only not-students, unset all results and therefore return 0 results - even though there _are_ results in the db – AD7six Jul 09 '13 at 09:09
  • true, your answer is better – Alex Stallen Jul 09 '13 at 09:15