Cakephp HABTM (Has and Belongs to Many)

1st Aug 2013 at 2:28 PM | Posted in CAKEPHP, PHP | Leave a comment

HABTM is toughest model association in Cakephp. Lets explore this:
There are many mobile phones and they have many features, this can be good example of HABTM.
A mobile may have many features and a feature may belongs to many mobiles.

Create Below tables:
CREATE TABLE IF NOT EXISTS `cake_mobiles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
)


CREATE TABLE IF NOT EXISTS `cake_features` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
)


CREATE TABLE IF NOT EXISTS `cake_features_mobiles` (
`mobile_id` int(11) NOT NULL,
`feature_id` int(11) NOT NULL
)



Create File: app\Controller\MobilesController.php

<?php
class MobilesController extends AppController {
	public $uses	= array('Feature', 'Mobile');
	
	function index() {
		$data	= $this->Mobile->find('all');
		$this->set('data',$data);
	}
	function add($id=null) {
		if ($this->data) {	
			if($this->Mobile->save($this->data)) {
				$this->Session->setFlash('Category has been saved.');
				$this->redirect(array('controller'=>'mobiles','action'=>'index'));
			}
        }
		if($id) {
			$this->Mobile->id = $id;
			$this->request->data = $this->Mobile->read();
			
		}
		$features	= $this->Feature->find('list');
		$this->set('features',$features);
	}
	function delete($id) {
		$this->Mobile->id = $id;
		$this->Mobile->delete();
		//$this->autoRender = false;
		$this->redirect(array('controller'=>'mobiles','action'=>'index'));
	}
}

Create model: app\Model\Mobile.php

<?php
Class Mobile extends AppModel {
	public $name	= 'Mobile';
	var $hasAndBelongsToMany = array('Feature'=>array('className'=>'Feature'));
	public $validate = array(
        'title'			=> array(
			'emptychk' 		=> array(
				'rule' 		=> 'notEmpty',
				'message' 	=> 'Title can not be left empty'
			),
			'duplicatechk' 	=> array(
				'rule' 		=> 'isUnique',
				'message' 	=> 'This Title is already Exists, Please enter different'
			)
		),
		'Feature' => array( 
            'multiple' => array( 
                'rule' => array('multiple',array('min' => 1)), 
                'message' => 'Please select at least 1 feature'), 
        ), 
	);
	
function beforeValidate() {
	foreach($this->hasAndBelongsToMany as $k=>$v) {
		if(isset($this->data[$k][$k]))
		{
			$this->data[$this->alias][$k] = $this->data[$k][$k];
		}
	}
}


}



View file: app\View\Mobiles\index.ctp

<?php echo $this->Html->link('Add',array('action'=>'add/'));?>
<table>
<tr>
	<th width="70%">Name</th>
	<th>Action</th>
</tr>

<?php foreach($data as $mobile) {?>
	<tr>
		<td><?php echo $mobile['Mobile']['title'];?></td>
		<td>
			<?php echo $this->Html->link('Edit',array('action'=>'add/'.$mobile['Mobile']['id']));?>
			<?php echo $this->Html->link('Delete',array('action'=>'delete/'.$mobile['Mobile']['id']),array('confirm' => 'Are you sure you want to delete this banner?'));?>
		</td>
	</tr>
<?php } ?>

</table>

View file: app\View\Mobiles\add.ctp

<?php 
echo $this->Session->flash();
echo $this->Form->create('Mobile');
echo $this->Form->input('title');

echo $this->Form->input('Feature', array(
                        'options' 	=> $features,
						'multiple'	=>'checkbox'
                        )
					);
echo $this->Form->input('id',array('type'=>'hidden'));
echo $this->Form->submit('Save',array('label'=>false));					
echo '<div class="actions">';
echo $this->Html->link('Cancel',array('action'=>'index'));
echo '</div>';

				
echo $this->Form->end();
?>

Now create files for features

File: app\Controller\FeaturesController.php

<?php
class FeaturesController extends AppController {
	public $uses	= array('Feature', 'Mobile');
	function index() {
		$data	= $this->Feature->find('all');
		$this->set('data',$data);
	}
	function add($id=null) {
		if ($this->data) {	
			if($this->Feature->save($this->data)) {
				$this->Session->setFlash('Feature has been saved.');
				$this->redirect(array('controller'=>'features','action'=>'index'));
			}
        }
		if($id) {
			$this->Feature->id = $id;
			$this->request->data = $this->Feature->read();
		}
		$mobiles	= $this->Mobile->find('list');
		$this->set('mobiles',$mobiles);
	}
	function delete($id) {
		$this->Feature->id = $id;
		$this->Feature->delete();
		$this->redirect(array('controller'=>'features','action'=>'index'));
	}
}

Model File : app\Model\Feature.php

<?php
Class Feature extends AppModel {
	public $name	= 'Feature';
	var $hasAndBelongsToMany = array('Mobile'=>array('className'=>'Mobile'));
	public $validate = array(
        'title'			=> array(
			'emptychk' 		=> array(
				'rule' 		=> 'notEmpty',
				'message' 	=> 'Title can not be left empty'
			),
			'duplicatechk' 	=> array(
				'rule' 		=> 'isUnique',
				'message' 	=> 'This Title is already Exists, Please enter different'
			)
		)
	);
}

View files: app\View\Features\index.ctp

<?php echo $this->Html->link('Add',array('action'=>'add'));?>
<table>
<tr>
	<th width="70%">Name</th>
	<th>Action</th>
</tr>

<?php foreach($data as $feature) {?>
	<tr>
		<td><?php echo $feature['Feature']['title'];?></td>
		<td>
			<?php echo $this->Html->link('Edit',array('action'=>'add/'.$feature['Feature']['id']));?>
			<?php echo $this->Html->link('Delete',array('action'=>'delete/'.$feature['Feature']['id']),array('confirm' => 'Are you sure you want to delete this banner?'));?>
		</td>
	</tr>
<?php } ?>

</table>

View files: app\View\Features\add.ctp

<?php 
echo $this->Session->flash();
echo $this->Form->create('Feature');
echo $this->Form->input('title');

echo $this->Form->input('id',array('type'=>'hidden'));

echo $this->Form->input('Mobile', array(
                        'options' 	=> $mobiles,
						'multiple'	=>'checkbox'
                        )
					);

					
					
echo $this->Form->submit('Save',array('label'=>false));					
echo '<div class="actions">';
echo $this->Html->link('Cancel',array('action'=>'index'));
echo '</div>';

				
echo $this->Form->end();
?>

Everything done. Have fun.

Advertisements

Leave a Comment »

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: