• 2nd July 2009 - By dan

    Right,

    When I started out on this I hit t’internet looking for any kind of hints as to the best way of going about this. The first thing I came across was the use of a Self Referential HABTM relationship ( User<-HABTM->User ), naturally not being the uber Cake Nerd this really didnt work out too well for me ( although if you want to do it this way it will work if you follow my previous post about redirects after save() ).

    So after deciding to scrap the HABTM relationship and move over to a hasMany() / belongsTo() association things became much easier.

    I have the following tables:

    • users
    • friends

    basically in this friends acts as the “HABTM” join table (basically it is the table we write the associations into – user_id(1) is friends with user_id(2) blah blah blah).

    My friends model looks like this:

    class Friend extends AppModel {  	 
    var $name = 'Friend';   
    }

    Nice eh?

    Ok my user profile has the following(stripped down for conciseness). I use Bake for my code generation as it generally does a much better job at finding associations – just bear in mind that you will need to have good DB design skills and remember to name foreign keys correctly for it to work.

     
    class User extends AppModel {
     
    	var $name = 'User';
    	var $validate = array(
    		'username' => array('notempty'),
    		'password' => array('notempty'),
    		'group_id' => array('numeric'),
    		'active' => array('numeric'),
    		'email' => array('email'),
     
    	var $belongsTo = array(
    		'Group' => array(
    			'className' => 'Group',
    			'foreignKey' => 'group_id',
    			'conditions' => '',
    			'fields' => '',
    			'order' => ''
    		)
    	);
     
    	var $hasMany = array(
    		'Friend' => array(
    			'className' => 'Friend',
    			'foreignKey' => 'user_id',
    			'dependent' => false,
    			'conditions' => '',
    			'fields' => '',
    			'order' => '',
    			'limit' => '',
    			'offset' => '',
    			'exclusive' => '',
    			'finderQuery' => '',
    			'counterQuery' => ''
    		)
    	);
     
    	var $hasAndBelongsToMany = array(
    		'Group' => array(
    			'className' => 'Group',
    			'joinTable' => 'groups_users',
    			'foreignKey' => 'user_id',
    			'associationForeignKey' => 'group_id',
    			'unique' => true,
    			'conditions' => '',
    			'fields' => '',
    			'order' => '',
    			'limit' => '',
    			'offset' => '',
    			'finderQuery' => '',
    			'deleteQuery' => '',
    			'insertQuery' => ''
    		)
    	);
     
    }

    And basically that is it. You will need a piece of code in your controller (or model I guess) that actually adds the friend (ask and you shall receive:)

    function addfriend($user_id, $friend_id) {
        	//$user_id = $this->Session->read('User'); //when logged in disabled for testing
            $this->data['Friend']['user_id'] = $user_id;
            $this->data['Friend']['friend_id'] = $friend_id;
            $this->data['Friend']['accepted'] = 0;
            $this->data['Friend']['rejected'] = 0;
            //print_r($this->data);
            $this->User->Friend->Create();
            $count = $this->User->Friend->find('count', 
            		array('conditions' => 
            				array(	'user_id' => $user_id, 
            						'friend_id' => $friend_id)));
            if( $count < 1) {
    	        if($this->User->Friend->save($this->data)){
    	                $this->Session->setFlash('Friend Added');
    	                $this->redirect('/user_profiles/view/'.$this->User->UserProfile->profileID($user_id));
    	                exit;
    	        } else {
    	                $this->Session->setFlash('Error Adding Friend');
    	                exit;
    	        }
     
    		} else {
    			$this->Session->SetFlash('That Friend Exists');
    			$this->redirect('/user_profiles/view/'.$this->User->UserProfile->profileID($user_id));
    			exit;
    		}
    	}

    One thing ill state is that the whole

     $count = $this->User->Friend->find('count', 
            		array('conditions' => 
            				array(	'user_id' => $user_id, 
            						'friend_id' => $friend_id)));
            if( $count < 1) {

    is pretty lame on my part – the correct way would be to create a validation rule in your model but im in a bit of a rush and just need to get this part working.

    Hope this helps – obviously you just call /users/addfriend/1/2 or something similar to add a friend and then the rest should all come together.

    Dan

    Share with your friends and help out this site:
    • Digg
    • del.icio.us
    • Facebook
    • Google Bookmarks
    • E-mail this story to a friend!
    • LinkedIn
    • Live
    • Reddit
    • StumbleUpon
    • Twitter
    • Yahoo! Bookmarks

Ad