Hi all, I really tried to pull this thing by myself, but there's always something that's not working as expected.
I have a user-and-friend situation. I need to have both the friend requests and the accepted friendships in the same table. Hence, the extra fields in the HABTM join table. I also need to be able to retrieve the pending incoming and outgoing requests for the current user, together with any additionally associated models (User hasMany Photo, etc.). I need to be able to paginate and sort those pending requests. I need to retrieve the currently established friendships for the current user (logged user id is either user_id or friend_id in the join table) Reading through quite some articles, I based my setup on two of them: http://groups.google.com/group/cake-php/msg/fae9ec58501534e6? by AD7six http://www.cricava.com/blogs/index.php?blog=6&title=modelizing_habtm_join_tables_in_cakephp_&more=1&c=1&tb=1&pb=1 by Mariano Iglesias Mariano Iglesias describes two alternative approaches (using auto-with models vs. manually modeling the habtm association). I decided to go for modeling the join table, because I intended to use AD7six's Pagination component and I have prior experience with that component where I had to manually model the habtm join tables. So, here's my setup: [models/user.php]: var $hasMany = array( 'Photo' => array( 'className' => 'Photo', 'foreignKey' => 'user_id', 'order' => 'Photo.primary DESC, Photo.id ASC', 'dependent' => true, ), ); var $hasAndBelongsToMany = array( 'Friend' => array( 'className' => 'User', 'joinTable' => 'users_friends', 'foreignKey' => 'friend_id', 'associationForeignKey'=> 'user_id', 'unique' => true, 'with' => 'UserFriend', ), ); [models/user_friend.php]: class UserFriend extends AppModel { var $name = 'UserFriend'; var $useTable = 'users_friends'; var $belongsTo = array( 'User' => array( 'className' => 'User', 'joinTable' => 'users_friends', 'foreignKey' => 'user_id', 'associationForeignKey'=> 'friend_id', 'unique' => true, ), 'Friend' => array( 'className' => 'User', 'joinTable' => 'users_friends', 'foreignKey' => 'friend_id', 'associationForeignKey'=> 'user_id', 'unique' => true, ), ); } [DB tables]: CREATE TABLE `users` ( `id` mediumint(8) unsigned NOT NULL auto_increment, `group_id` smallint(6) NOT NULL, `email` varchar(100) default NULL, `username` varchar(50) NOT NULL, `password` varchar(50) default NULL, `active` tinyint(1) default '0', `created` datetime default NULL, `modified` datetime default NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `users_friends` ( `id` int(11) NOT NULL auto_increment, `user_id` int(10) unsigned NOT NULL default '0', `friend_id` int(10) unsigned NOT NULL default '0', `requested` datetime default NULL, `accepted` datetime default NULL, `active` tinyint(1) default '0', PRIMARY KEY (`id`), KEY `key_fan_friend` (`user_id`,`friend_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `photos` ( `id` int(11) NOT NULL auto_increment, `type` varchar(255) NOT NULL default '', `ext` varchar(255) NOT NULL default '', `size` int(11) NOT NULL default '0', `primary` tinyint(1) default '0', `user_id` int(11) NOT NULL, `created` datetime default NULL, `updated` datetime default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 Here are my results with this setup: [controllers/users_controller.php]: function requests() { $user_id = $this->othAuth->user('id'); $this->User->unbindAll( array( 'hasMany' => array('Photo'), 'hasAndBelongsToMany' => array('Friend'), ) ); $outgoingConditions = array( 'UserFriend.user_id' => $user_id, 'UserFriend.active' => 0, ); $incomingConditions = array( 'UserFriend.friend_id' => $user_id, 'UserFriend.active' => 0, ); $outgoing_requests = $this->User->UserFriend- >findAll($outgoingConditions); $incoming_requests = $this->User->UserFriend- >findAll($incomingConditions); $this->log($outgoing_requests, 'outgoing'); $this->log($incoming_requests, 'incoming'); } [app/tmp/logs/incoming.log] Array ( [0] => Array ( [UserFriend] => Array ( [id] => 3 [user_id] => 3 [friend_id] => 1 [requested] => 2007-11-21 17:43:14 [accepted] => [active] => 0 ) [User] => Array ( [id] => 3 [group_id] => 2 [email] => [EMAIL PROTECTED] [username] => JackDaniels [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 23:43:57 [modified] => 2007-10-24 23:46:20 ) [Friend] => Array ( [id] => 1 [group_id] => 2 [email] => [EMAIL PROTECTED] [username] => nasko [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 22:52:41 [modified] => 2007-10-24 22:52:41 ) ) ) [app/tmp/logs/outgoing.log] Array ( [0] => Array ( [UserFriend] => Array ( [id] => 1 [user_id] => 1 [friend_id] => 2 [requested] => 2007-11-21 16:23:50 [accepted] => [active] => 0 ) [User] => Array ( [id] => 1 [group_id] => 2 [email] => [EMAIL PROTECTED] [username] => nasko [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 22:52:41 [modified] => 2007-10-24 22:52:41 ) [Friend] => Array ( [id] => 2 [email] => [EMAIL PROTECTED] [username] => nasko2 [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 23:00:33 [modified] => 2007-10-24 23:01:46 ) ) ) So far, so good - I've achieved an output similar to what Mariano is describing in his article. The probelm emerges when I try to retrieve the photos of requesting or requested users. As Mariano is suggesting, I started to play with the recursive argument of the findAll() call: $outgoing_requests = $this->User->UserFriend- >findAll($outgoingConditions,null,null,null,null,2); $incoming_requests = $this->User->UserFriend- >findAll($incomingConditions,null,null,null,null,2); #1. I'm getting notices in the browser output: Notice (8): Undefined index: User [CORE\cake\libs\model\datasources \dbo_source.php, line 772] Notice (8): Undefined offset: 0 [CORE\cake\libs\model\datasources \dbo_source.php, line 875] #2. The log files: [app/tmp/logs/incoming.log] Array ( [0] => Array ( [UserFriend] => Array ( [id] => 3 [user_id] => 3 [friend_id] => 1 [requested] => 2007-11-21 17:43:14 [accepted] => [active] => 0 ) [User] => Array ( [id] => 3 [email] => [EMAIL PROTECTED] [username] => JackDaniels [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 23:43:57 [modified] => 2007-10-24 23:46:20 [Photo] => Array ( [0] => Array ( [id] => 26 [type] => image/jpeg [ext] => jpg [size] => 1185725 [primary] => 1 [user_id] => 3 [created] => 2007-11-15 14:54:41 [updated] => 2007-11-15 14:54:41 ) ) [Friend] => Array ( ) ) [Friend] => Array ( [id] => 1 [email] => [EMAIL PROTECTED] [username] => nasko [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 22:52:41 [modified] => 2007-10-24 22:52:41 ) ) ) [app/tmp/logs/outgoing.log] Array ( [0] => Array ( [UserFriend] => Array ( [id] => 1 [user_id] => 1 [friend_id] => 2 [requested] => 2007-11-21 16:23:50 [accepted] => [active] => 0 ) [User] => Array ( [id] => 1 [email] => [EMAIL PROTECTED] [username] => nasko [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 22:52:41 [modified] => 2007-10-24 22:52:41 [Photo] => Array ( [0] => Array ( [id] => 27 [type] => image/pjpeg [ext] => jpg [size] => 1443536 [primary] => 1 [user_id] => 1 [created] => 2007-11-16 15:56:42 [updated] => 2007-11-16 15:56:42 ) [1] => Array ( [id] => 18 [type] => image/jpeg [ext] => jpg [size] => 1410154 [primary] => 0 [user_id] => 1 [created] => 2007-11-15 01:27:01 [updated] => 2007-11-15 01:27:01 ) [2] => Array ( [id] => 21 [type] => image/pjpeg [ext] => jpg [size] => 1532595 [primary] => 0 [user_id] => 1 [created] => 2007-11-15 12:41:27 [updated] => 2007-11-15 12:41:27 ) [3] => Array ( [id] => 22 [type] => image/jpeg [ext] => jpg [size] => 1395255 [primary] => 0 [user_id] => 1 [created] => 2007-11-15 13:14:33 [updated] => 2007-11-15 13:14:33 ) [4] => Array ( [id] => 23 [type] => image/jpeg [ext] => jpg [size] => 1980160 [primary] => 0 [user_id] => 1 [created] => 2007-11-15 14:54:10 [updated] => 2007-11-15 14:54:10 ) ) [Friend] => Array ( [0] => Array ( [id] => 3 [email] => dolor.sitamet [EMAIL PROTECTED] [username] => JackDaniels [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 23:43:57 [modified] => 2007-10-24 23:46:20 [UserFriend] => Array ( [id] => 3 [user_id] => 3 [friend_id] => 1 [requested] => 2007-11-21 17:43:14 [accepted] => [active] => 0 ) ) [1] => Array ( [id] => 4 [email] => dolor.sitamet [EMAIL PROTECTED] [username] => jackline [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 23:50:45 [modified] => 2007-10-24 23:51:45 [UserFriend] => Array ( [id] => 4 [user_id] => 4 [friend_id] => 1 [requested] => 2007-11-21 17:43:39 [accepted] => 2007-11-21 17:43:39 [active] => 1 ) ) ) ) [Friend] => Array ( [id] => 2 [email] => [EMAIL PROTECTED] [username] => nasko2 [password] => 6a496d870428fbe5fbf6ce086ed6a96e [active] => 1 [created] => 2007-10-24 23:00:33 [modified] => 2007-10-24 23:01:46 ) ) ) It looks like the associated models for the Friend part of the HABTM association are not fetched, regardless of the direction of the request: for incoming friend requests I can see the associated Photo model of the requesting user, but for requests that I initiate I cannot see the photos of the target user... Judging from the above mentioned articles I shouldn't create a model w/ class for the Friend association, since I'm specifying className => 'User' I also tried the other approach - without having the UserFriend model, also withouth the 'with' key of the association table, but dinamycally binding the auto-with join model: $this->User->UserFriend->bindModel(array('belongsTo' => array('User', 'Friend'))); I'm getting identical results as with modeling the join table. I know this stuff has been extensively discussed, but I don't seem to be able to grasp it in its entirety.... I'd be extremely thankful if anyone could hint me as to what I might be doing wrong and what I need to change in my setup to achieve the requirements specified above. Thank you in advance! Regards, Nasko --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Cake PHP" group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~----------~----~----~----~------~----~------~--~---