Set find() conditions in the model

Hi everybody, I'm brand new to CakePHP and I'm discovering with pleasure its features :)

Is there a "Model property"-like manner (or a property; I couldn't find one in the API doc) to set the find 'fields' and 'conditions' conditions ?

Instead of doing

$this->Model->find('all', array('conditions' => ...))

in my Controller, I want to add these conditions to my Model so I only need to

$this->Model->find('all')

in my controller and the conditions will be added automatically by the Model when querying the database.

I found that there is an 'order' model property that behaves like that, but none for these above.

I want to do this because I have a table that contains a lot of fields which are not relevant for some models that use this table, and these models always need at least one fixed WHERE condition (I use MySQL).

For some reason I can't adapt the DB to my Models structure, and I want that my controllers don't have to care about filtering fields in DB queries because of a bad designed DB (it's not their role).

Is there a pretty manner to solve this ?

Asked by CrazyGolem, on 29/1/10

3 Answers

i would be hesitant to completely re-write the find function - this should work for you:

in your model:


public function customFind($conditions = null, $options = array(), $order = null, $recursive = null) {
    $options['conditions'] = array('foo' => 'bar');
    return parent::find($conditions, $options, $order, $recursive);
}

in your controller:


$this->Model-> customFind('all');

Answered by patrickisftwon 29/1/10

This solution would be my last one, as I don't find it very pretty. Can't ContainableBehavior be a solution ? It looks like this behavior is able to filter the query by fields value, and remove some retrieved fileds. Plus it can be initialized and parametrized (which fields are filtered/removed ?) from inside my model. Am I correct ?

CrazyGolem - on 29/1/10

<< comments | comments >>

Putting the conditions which define the relationships, it would be a way out?

Answered by MichaelMaforton 29/1/10

I don't really understand what you mean, but if it's something like "the relationships between my model and the table" it might be what I'm looking for.

I give you one example : If my table is

field1 - field2 - field3 - field4

My model defines an object that uses (retrieves) only field1 and field3, and only if field4 is set to "bar"

The MySQL request for a simple find('all') in a controler that uses this model should look like

`SELECT field1, field3 FROM table WHERE field4 LIKE 'bar'

And if conditions are added to the find(), like find('all', array('conditions' => array('field1' => 'foo'))) the corresponding MySQL request should look like

SELECT field1, field3 FROM table WHERE field4 LIKE 'bar' AND field1 LIKE 'foo'

CrazyGolem - on 29/1/10

<< comments | comments >>

I use wrapper functions to keep any model-specific logic within the model.


Model:
function get($id) {
  return $this->findById($id);
}

function getAll() {
  return $this->find('all', array(...));
}

Controller:
$this->set('result', $this->Model->get($id));

Answered by dirnon 1/2/10

I'm not rewriting find(). Like I said, these are wrapper functions.

Using find() in a controller is already using a model-specific method. My wrappers eliminate the $params array, which is where all the model-specific stuff really lives. If you mean that you don't want to remember which models have wrapper methods and which ones don't, do what I do and put them in AppModel.

Let's say you want to find a record by ID, but only if the is_active field is set to 1. With find() you'd have to do something like $this->Model->find('first', array('conditions' => array('Model.id' => $id, 'Model.is_active' => 1)));. With my wrappers, I'd make a function called getActive() that wraps around the find() call, and my controller only needs to know $this->Model->getActive($id);.

This also has the advantage that should the Cake team decide to change find() again (like they did from 1.1 to 1.2), you only have to rewrite the wrapper functions in your models and/or AppModel, not every controller, model, etc. using find().

dirn - on 3/2/10

<< comments | 1 | 2
<< previous next >>

Your Answer

You can use Creole Wiki Syntax to format your text.

Tagged with

Rating

0

Viewed

529 times

Last Activity

on 3/2/10