Using afterFind() to create pseudofields in CakePHP
CakePHP provides a useful model function, afterFind(), which can be used to manipulate results returned from any find(), findAll() or findBy<field>() query.
Tagged with CakePHP and Web Development
Posted on 6/5/07 by Paul Herron
One useful application of this feature is in merging data from two or more database fields into one pseudofield. In the example below, afterFind() is added to a User model. A foreach statement takes the firstName and lastName fields for each user and creates a new field, fullName.
<?php class User extends AppModel { var $name = 'User'; function afterFind($results) { // For any results returned from the 'User' model, take 'firstName' and 'lastName' and use them to produce a 'fullName' pseudofield. foreach ($results as $key => $val) { $results[$key]['User']['fullName'] = $val['User']['firstName'] . ' ' . $val['User']['lastName']; } } return $results; } } ?>
CakePHP makes $results available automatically, and automatically deals with them when they're returned from the afterFind(), so this function should work 'as is'.
All being well, a find(), findAll() or findBy query in the controller will now give an array structure like this:
( [0] => ( [firstName] => Graeme [lastName] => Garden [fullName] => Graeme Garden ) [1] => ( [firstName] => Tim [lastName] => Brooke-Taylor [fullName] => Tim Brooke-Taylor ) )
afterFind() can result in significantly tidier code, and puts this kind of processing where it belongs - in the model. It's also a useful workaround for inserting more than one field into a generateList() statement. The label parameter in generateList() can only be sourced from one field, but this can be the pseudofield generated in the example above.
$this->set('users', $this->User->generateList(null,null,null,'{n}.User.id','{n}.User.fullName'));
This would set a $users array for use in the view, and could be used be used to output a select box with each option set to a user's full name.
Comments
Leave a Comment
Article Tags
Show all articles, or just those tagged as:
- Apache (1)
- CakePHP (10)
- Domains (1)
- Freeware (1)
- Graphics (1)
- Life (1)
- Open Source (2)
- Servage (1)
- SMS (1)
- Software (3)
- Ubuntu (2)
- WAMP (2)
- Web Development (13)
- Windows (2)
- Work (2)
Feed
The articles RSS feed is available.
Elsewhom
-
GNOME Coder.
Modern open source software development -
Coding My Thoughts.
Java, PHP, and some other technological mumble jumble. Also, some real-life stuff as well. -
FFFFOUND!.
Image bookmarking -
graphpaper.
Art Science Business -
RichardHerring.com.
Home of the comedian and online journal-keeper

Tane Piper wrote on 18/7/07:
Hey - great article! Works a treat in my application for generateList and having more than one value!Phil McGuire wrote on 31/7/07:
Thanks for the article! Just what I needed but there's a syntax error in it just so you know.
if (isset($val['User']['firstName']) && (isset($val['User']['lastName'])) {
should be:
if (isset($val['User']['firstName']) && isset($val['User']['lastName'])) {
Thanks!
Paul Herron wrote on 25/8/07:
Hi Phil,
Glad you found it useful!
Thanks for the info on the mistake - that's amended now.
Mike wrote on 24/6/08:
Hey.
Nice tip, I was struggling to find out how to do this for a while, but it works like a charm.
Thank, Mike.
zoli wrote on 25/10/08:
Thanks, very useful article!
Wouldn't need such inventions if CakePHP would be a true OOP framework, but... c'est la vie. I suggest using Ruby on Rails instead.
Bennigraf wrote on 3/11/08:
Hi there!
Thanks for your hint - I came across by chance and it helped me alot already, although it's kind of old. I just discovered one problem: When only one result is returned (both on purpose using find('first') and just using conditions) cake creates the $results-array without the numeric indizes for which your way doesn't sets the fullname, since $key is already 'User' and val contains the indizes 'firstName' and 'lastName' directly.
Any Ideas on how to work around this except adding another if (like if(isset($var['firstName'] && ...))?
Greetings, Benni.
Nate Klaiber wrote on 7/11/08:
I would agree with zoli. This is a lot of extra work to get a 'full_name' method. If CakePHP would be truly OOP, then I could have an instance method - and I wouldn't need any extra loops to iterate over and add such methods. I just can't see how this is a good design decision.dogmatic wrote on 29/4/09:
@Nate
if you think its not so good why not supply a better solution then?
Heryudi Ganesha wrote on 28/7/09:
Hi, thanks for the tips! But when I'm using it like, example:
if ($val['Posting']['amount'] == 1) {
This gives me following notice:
Undefined index: Posting [APP\models\posting.php, line 38]
Line 38: if ($val['Posting']['amount'] == 1) {
The logic in the afterFind callback works perfectly the way it's supposed to do.
Any idea why cakephp display the notice?
Atea Webdevelopment wrote on 12/4/10:
Any clues on what I need to do to sort on a pseudofield?
Should I add a custom Mysql query?
I need to sort on someting like this:
COALESCE(price_month_action, price_month_regular) AS price_month_least