The question of creating a select box with CakePHP has come up many times. Actually, it's very simple, although not bleeding obvious. ;-)
This example is for CakePHP 1.2
Let's assume you have two models, Article and Category. The relations are set up like this:
- Article -belongsTo-> Category
- Category -hasMany-> Article
So you need to show a list of categories when you want to add or edit and article.
First of all, you controller will look like this:
class ArticlesController extends AppController { var $name = 'Articles'; var $uses = array('Article'); }
Now, in your controller, to keep it DRY, we define a private function which will setup the categories for our view.
class ArticlesController extends AppController { // snip... function _setCategories() { $categories = $this->Article->Category->find ( 'list', array ( 'fields' => array('id', 'name'), 'order' => 'Category.name ASC', 'recursive' => -1 ) ); $this->set(compact('categories')); } // snip... }
The important thing to note here, is the parameter "list" instead of "all". When you do a find('list', ...) CakePHP will automagically generate a list of options ready to use with the FormHelper. But, let's see that one by example.
In your add() and/or edit() action of the controller, you have this:
class ArticlesController extends AppController { // snip... function add($slug = null) { $this->_setCategories(); // your other stuff here } function edit($slug = null) { $this->_setCategories(); // your other stuff here } // snip... }
Now comes the fun part. All you have to do in your view now is the following:
// this would go in your ~/app/views/articles/add.ctp (and/or edit.ctp) <?php echo $form->select ( 'Article.category_id', // name of the field in Article model $categories, // the var we've set in _setCategories() null, array(), false ); ?>
This should give you a nice select box with your categories listed alphabetically. Pretty damn neat, right?
Alternatively, if you don't want to lose the cake magic by using $form->select, you can still use $form->input like this:
<?php echo $form->input ( 'Article.category_id', array ( 'options' => $categories ) ); ?>
CakePHP does all the magic for you. Still, if you need different options than those described here, take a look at the API reference for Model::find()[1], FormHelper::select()[2] and FormHelper::input()[3]. Please note that I've typed all this from my memory, so if you find any typos let me know ;-)
Happy baking!
Article comments — View · Add
Also, I remember the time when I didn't know that I can access the related model via $this->Article->Category, so what I used to do was:
var $uses = array('Article', 'Category');
I was so wrong... :-/
(In fact, I think this code is still running my site)
Inflector::varName(Inflector::pluralize(preg_replace('/_id$/', '', $fieldName)))
wich means that, for Post.category_id you should have a "categories" var passed to the view, and for Employee.soccer_team_id you should have a "soccerTeams"
as shown in FormHelper's source line 607: http://api.cakephp.org/form_8php-source.html#l00607
BTW, I didn't like the fact that I can't post a comment while seeing other people comments, I can't cite them or use as reference... but that's my opinion of course...
thanks for the tip, that's a good one.
We'll see about the comments, it will probably be done in a future (but unspecified!:)) release of Neutrino.
Oh, and thanks.