Hassan
Hassan

Reputation: 1

hasMany combo box in cakePHP

I am a new cake baker. I developing a web site for cars, where each carcategory has many cars, and each car belongs only to one carcategory. In my Cars model, I wrote the following code:

    class Cars extends AppModel 
    {
     var $name = 'Cars';
     var $belongsTo = array('Carcategory','User');
    }  

And in my Carcategory model, I wrote the following code:

    class Carcategory extends AppModel {
        var $name = 'Carcategory';
        var $hasMany = array(
        'Car' => array(
            'className'     => 'Car',
            'foreignKey'    => 'carcategory_id',
            'order'    => 'carcategory.name ASC',
            'dependent'=> true
        )
    );

}  

And in my car_controller, I wrote the following code:

    function beforeFilter(){
 $this->set('car_categories',$this->Carcategory->find('list', array('order' => 'name')));
  }

And in my car view, I wrote the following code:

echo $form->input('carcategory_id', array('options' => $car_categories, 'label' => 'Cars Categories : ', 'class' => 'short'));  

My database tables are as the following:

    CREATE TABLE `carcategories` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `image` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;  

     CREATE TABLE `cars` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(255) character set utf8 collate utf8_bin NOT NULL,
  `name` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL,
  `model` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `motorcc` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `details` text character set utf8 collate utf8_unicode_ci NOT NULL,
  `carcategory_id` int(11) NOT NULL,
  `userid` int(11) NOT NULL,
  `hits` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;  

I have named the first table carcategory, because I might add another services to my site, and these services might have other categories
My code generates the following error

    Notice (8): Undefined property: CarsController::$Carcategory [APP\controllers\cars_controller.php, line 14]
Fatal error: Call to a member function find() on a non-object in c:\wamp\www\work\cake\app\controllers\cars_controller.php on line 14

I cannot figure out what is the wrong in my code. Please give me a hand
Thanks

Upvotes: 0

Views: 1513

Answers (2)

RabidFire
RabidFire

Reputation: 6330

First off, you're not sticking to the CakePHP naming conventions. (Check them out here) Doing this would help you spot little mistakes, like the classname for your model is Cars when it should be Car. I would also rename your table to car_categories and hence all occurrences of Carcategory to CarCategory.

models/car.php

class Car extends AppModel {
    var $name = 'Car';
    var $belongsTo = array('CarCategory', 'User');
}

models/car_category.php

class CarCategory extends AppModel {
    var $name = 'CarCategory';
    var $hasMany = array(
        'Car' => array(
            'className' => 'Car',
            'foreignKey' => 'car_category_id',
            'order' => 'CarCategory.name ASC',
            'dependent' => true
        )
    );
}

controllers/cars_controller.php

function beforeFilter() {
    $this->set('carCategories', $this->Car->CarCategory->find('list'));
}

Note: You don't need to specify the order because you've already mentioned it in the model as the default order. Also, note the naming conventions for the view variable. This would let us do some CakePHP magic and simply type this in the view:

view

echo $form->input('car_category_id', array('class' => 'short'));

Again, not to be pedantic, but the label should be Car Category instead of Car Categories as you have it now, since a Car can belong to only one category according to your data model.

If you want the ":" separator for all your labels, you can use CSS to add them. Check here to find out how. You can also specify the between option for the form input.

Tables

Rename the table carcategories to car_categories Rename the column carcategory_id in the cars table to car_category_id

Coming back to your actual problem:

Undefined property: CarsController::$CarCategory

This means that you cannot access CarCategory model from the CarsController. By default, the CarsController would manage the Car model. In order to manage the CarCategory model, you can do it in one of many ways:

  • Using associations: $this->Car->CarCategory->find( ... )
  • In your controller, set the $uses variable as follows: var $uses = array('Car', 'Carcategory');

You can load models on-the-fly as well (using loadModel or ClassRegistry::init if you're interested), but since you're fetching the list of Car Categories in the beforeFilter, you should stick to one of the above methods (preferably the associations).

Hope that helps. Remember to look carefully at the names of all your models, controllers, files and tables.

Upvotes: 1

RSK
RSK

Reputation: 17516

In your car controller the find should be

$this->set('car_categories',$this->Car->Carcategory->find('list', array('order' => 'name')));

Upvotes: 0

Related Questions