CakePHP allows you to use your own "find-types" for the Model::find() methodology. Those of your who are familiar with the find() method know that there are currently four types in the core: 'list', 'all', 'first' and 'count'. However, sometimes it is nice to specify your own type so you can have a call like this:
$this->Comment->find('pending');
So how would you go about implementing this? Correct, you would
overwrite the find() method in your model and provide the default
functionality if there is one of the default types used. Let's have a
look at how you could implement this pending find from above:
class Comment extends AppModel {
var $belongsTo = array('User');
function find($type, $queryData = array()) {
switch ($type) {
case 'pending':
return $this->find('all', array(
'fields' => array('User.email', 'User.first_name', 'User.last_name', 'Comment.name')
, 'conditions' => array(
'Comment.active' => 0
, 'Comment.blocked' => 0
)
, 'contain' => array('User')
));
default:
return parent::find($type, $queryData);
}
}
}
So this is actually not very difficult code, but it is very powerful.
You could specify different sets of conditions, fields, orders, groups
by's and containments just by adding a new entry to the switch
statement. Please note that there is no break needed within the switch
as we return home.var $belongsTo = array('User');
function find($type, $queryData = array()) {
switch ($type) {
case 'pending':
return $this->find('all', array(
'fields' => array('User.email', 'User.first_name', 'User.last_name', 'Comment.name')
, 'conditions' => array(
'Comment.active' => 0
, 'Comment.blocked' => 0
)
, 'contain' => array('User')
));
default:
return parent::find($type, $queryData);
}
}
}
Let's add some code for finding pending users that were invited by the currently logged-in user. This is what we could use in the controller:
class Comment extends AppModel {
var $belongsTo = array('User');
function find($type, $queryData = array()) {
$defaults = array(
'conditions' => null
, 'fields' => array()
, 'order' => null
, 'recursive' => null
, 'contain' => null
);
$queryData = am($defaults, $queryData);
switch ($type) {
case 'pending':
return $this->find('all', array(
'fields' => am(
array('User.email', 'User.first_name', 'User.last_name', 'Comment.name')
, $queryData['fields']
)
, 'conditions' => am(array(
'Comment.active' => 0
, 'Comment.blocked' => 0
), $queryData['conditions'])
, 'contain' => am(array('User'), $queryData['contain'])
));
default:
return parent::find($type, $queryData);
}
}
}
With some default values we can happily use our custom find type
alongside dynamic conditions inserted by our controllers. If you think
this am() stuff is overkill, you could as well just provide another find
type:var $belongsTo = array('User');
function find($type, $queryData = array()) {
$defaults = array(
'conditions' => null
, 'fields' => array()
, 'order' => null
, 'recursive' => null
, 'contain' => null
);
$queryData = am($defaults, $queryData);
switch ($type) {
case 'pending':
return $this->find('all', array(
'fields' => am(
array('User.email', 'User.first_name', 'User.last_name', 'Comment.name')
, $queryData['fields']
)
, 'conditions' => am(array(
'Comment.active' => 0
, 'Comment.blocked' => 0
), $queryData['conditions'])
, 'contain' => am(array('User'), $queryData['contain'])
));
default:
return parent::find($type, $queryData);
}
}
}
$this->Comment->find('pending-created-by-logged-in-user');
class Comment extends AppModel {
var $belongsTo = array('User');
function find($type, $queryData = array()) {
switch ($type) {
case 'pending':
return $this->find('all', array(
'fields' => array('User.email', 'User.first_name', 'User.last_name', 'Comment.name')
, 'conditions' => array(
'Comment.active' => 0
, 'Comment.blocked' => 0
)
, 'contain' => array('User')
));
case 'pending-created-by-logged-in-user':
return $this->find('all', array(
'fields' => array('User.email', 'User.first_name', 'User.last_name')
, 'conditions' => array(
'Comment.active' => 0
, 'Comment.blocked' => 0
, 'Comment.created_by_id' => User::get('id')
)
, 'contain' => array('User')
));
default:
return parent::find($type, $queryData);
}
}
}
... well you get the idea. By the way, do you notice how useful using
a static functions like this User::get() methods are for fetching
properties and data from the currently logged in user? More on that
later.var $belongsTo = array('User');
function find($type, $queryData = array()) {
switch ($type) {
case 'pending':
return $this->find('all', array(
'fields' => array('User.email', 'User.first_name', 'User.last_name', 'Comment.name')
, 'conditions' => array(
'Comment.active' => 0
, 'Comment.blocked' => 0
)
, 'contain' => array('User')
));
case 'pending-created-by-logged-in-user':
return $this->find('all', array(
'fields' => array('User.email', 'User.first_name', 'User.last_name')
, 'conditions' => array(
'Comment.active' => 0
, 'Comment.blocked' => 0
, 'Comment.created_by_id' => User::get('id')
)
, 'contain' => array('User')
));
default:
return parent::find($type, $queryData);
}
}
}
No comments:
Post a Comment