Ten Minus Two Ways to Skip Cake Defaults
“Convention over Configuration” – a smart, elegant and clever approach that has made CakePHP different from other PHP frameworks. When it works, its automagic mesmerizes our mind. Bonus, adhering a particular convention always increases the quality and maintainability of the code.
But still there are times when we can not stick to the convention. There are times when our minds want to fly higher; they don’t want to be caged by any rule! They want flexibility!
“Cake is too strict” / “Cake is not flexible at all” – I don’t know how may times I have heard complains like these about my beloved Cake. These are all rubbish; Cake is enough flexible to do almost anything you want. Here goes some ways to escape the convention.
Case #1. Database table names
According to Cake Convention, table names should be English plural with underscores in between the words, like users, big_brothers etc. If we have a model class named Post then the related database table is posts. This is what Cake thinks by default, it understands it automatically; you don’t have to write it down explicitly.
Yes, it is too cool! But what if we want something else, we want to use artikel table to get related with the Post model. In some cases we may need it, especially when we are using a legacy table. It is too simple,
class Post extends AppModel
{
var $useTable = 'artikel';
}
Case #2. Database configuration
We know by default Cake uses the ‘default’ configuration specified at /app/config/database.php. However, we may like to use a different database for only the Post model. Suppose, we have specified another database configuration named ‘anotherdb’ in the database.php and we want our Post model to use that configuration. That’s too as easy as drinking milk,
class Post extends AppModel
{
var $useDbConfig = 'anotherdb';
}
Case #3. Primary key
By default, Cake thinks the primary_key of any table is id. Sometime it may not be the case. You may have some other name for the primary key. Too simple,
class Post extends AppModel
{
var $primaryKey = 'tin_number';
}
Case #4. Join table
By convention, join table between books and categories should have the name books_categories. Suppose, in our case, the name of the join table is books2categories! It is also possible to fit in to the meticulous (!) framework CakePHP. Just change the value of the joinTable key to books2categories in $hasAndBelongsToMany array in respective Model, as an example in Book model,
var $hasAndBelongsToMany = array(
'Category' =>
array('className' => 'Category',
'joinTable' => 'books2categories',
…..
Case #5. Using different model, more than one model or no model
Assume, we want to use Book model from posts_controller.
It’s plain and simple, just add/change the $uses variable in PostsController,
var $uses = array(‘Book’);
Let’s say, We are now getting more demanding, we want to use both Book model and Post model in PostsController, yeah right, just have to do the following,
var $uses = array(‘Post’ , ‘Book’);
You have surely guessed what should be done to use no model at all,
var $uses = array();
Case #6. Foreign Key not in pattern tablename_id
By convention, foreign keys should have names like tablename_id. So, if our posts hasMany comments, the comments table should have a field named post_id that holds the id of the related record of the posts table. Assume, for the sake of the example that we don’t have any id field in the posts table and the primary of the posts table is ’slug’.
Suppose, we added a foreign key named ‘post_slug’ in the comments table. We can define it as the foreign key in Cake like this,
In Post model,
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'post_slug'
)
);
And in the Comment model,
var $belongsTo = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_slug'
)
);
And it will work like a charm!
Case #7. Modifying URL
Huh! Does Cake URLs should always be like http://yourhost.com/controller_name[/action_name][/parameters] ?
Not at all! If you find your URL structure boring and add some spice in it app/config/routes.php is your friend. Let’s say, we want to change http://yourhost.com/users/login to http://yourhost.com/signin. To do that open the app/config/routes.php and add the following line,
Router::connect('/signin', array('controller' => 'users', 'action' => 'login'));
Now you have a much prettier and shorter URL!
Case #8. Overriding layout
Every page that we create is by default comes inside the layout – “default.ctp“. Now, for some particular controller actions we may like to have a different layout. Doing that is pretty straightforward,
First create a separate layout inside app/views/layouts named another.ctp
Then inside the controller actions add the following line
$this->layout('another');
And you are done! The view for that action will be rendered inside the layout “another.ctp”
Thank you so much !
5 Comments
Jump to comment form | comments rss [?] | trackback uri [?]