UPDATED ANSWER IN RESPONSE TO COMMENTS
With a belongsTo
relationship, the foreign key should be in the current model.
This means that if you want to have a relationship where User belongsTo LastLogin, the users
table should have a last_login_id
field.
In your case you probably want to use a hasOne relationship instead, and you're going to have to use the MAX()
SQL function in the fields
key. Note that getting the last_login works completely independently of your User hasMany Login relationship. So if all you want is the last login you can remove the hasMany relationship and just leave the hasOne.
With the example code below you'll get this:
Output of /users/index:
Array
(
[User] => Array
(
[id] => 1
[name] => user1
[last_login] => 2011-05-01 14:00:00
)
[Login] => Array
(
[0] => Array
(
[id] => 1
[user_id] => 1
[created] => 2011-05-01 12:00:00
)
[1] => Array
(
[id] => 2
[user_id] => 1
[created] => 2011-05-01 13:00:00
)
[2] => Array
(
[id] => 3
[user_id] => 1
[created] => 2011-05-01 14:00:00
)
)
)
If you don't use the Model::afterFind() callback your results will look more like this (Login array snipped to save space):
Array
(
[User] => Array
(
[id] => 1
[name] => user1
)
[0] => Array
(
[last_login] => 2011-05-01 14:00:00
)
)
Example code:users table:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
)
logins table:
CREATE TABLE `logins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
User model:
class User extends AppModel {
var $name = 'User';
var $hasMany = array('Login');
var $hasOne = array(
'LastLogin' => array(
'className' => 'Login',
'fields' => array('MAX(LastLogin.created) as last_login')
)
);
// This takes the last_login field from the [0] keyed array and puts it into
// [User]. You could also put this into your AppModel and it would work for
// all find operations where you use an SQL function in the 'fields' key.
function afterFind($results, $primary=false) {
if (!empty($results)) {
foreach ($results as $i => $result) {
if (!empty($result[0])) { // If the [0] key exists in a result...
foreach ($result[0] as $key => $value) { // ...cycle through all its fields...
$results[$i][$this->alias][$key] = $value; // ...move them to the main result...
}
unset($results[$i][0]); // ...and finally remove the [0] array
}
}
}
return parent::afterFind($results, $primary=false); // Don't forget to call the parent::afterFind()
}
}
Users controller:
class UsersController extends AppController {
var $name = 'Users';
function index() {
$this->autoRender = false;
pr($this->User->find('all'));
}
}
'order' => 'Login.created DESC'
- as you are referring to theLogin
table? – Ross