Understanding CakePHP Associations
CakePHP uses the Model-View-Controller (MVC) concept as a framework to encapsulate the three basic layers of an application. Models, the component of the MVC framework that connect the application to the data, are especially good at describing relational databases. One of the questions that seems to come up alot on the CakePHP Group in one form or another, is what the practical difference is between the various relationship types (or associations) that CakePHP models can implement. I'll try to explain what's helped me keep them straight...
NOTE: This is not a tutorial on writing a CakePHP application, but rather a few tips for understanding associations. For more complete information on writing a CakePHP application, see the manual.
I remember studying basic genetics in biology in high school, and our teacher said that genetics is one of those topics that people have an extremely hard time understanding... until it just clicks -- then you can't understand why you didn't get it before. I feel that learning associations in CakePHP can be a similar issue. I've been writing relational database applications for several years, but I remember when I was defining models in my first Cake app... I couldn't for the life of me get a grip on what the difference between "hasOne" and "belongsTo" was, let alone the infamous hasAndBelongsToMany! That was, until I took a closer look at the CakePHP Manual chapter on Models and made an important discovery: the difference between hasOne and belongsTo lies in which table in the relationship does the 'pointing.'
belongsTo:
A -> B
If table A has a field that references table B, then table A is said to "belongTo" table B.
Just imagine that every record in the A table says "I belong to a record in table B!"
In the movie database example below, since for each movie there is one director, and the movie table has a field that points to a director, each movie belongs to a director. With belongsTo, each record can only be associated with one foreign record, but multiple records can be associated with any given foreign record. For instance, all three Matrix movies were directed by the Wachowski brothers, so each movie would belong to the Brothers' entry in the directors table.
hasOne:
A <- B
If only a single record in table B has a field that references table A, then table A is said to "hasOne" table B.
Every record in table A says: "I have one record in table B that points to me!"
hasOne is basically belongsTo, but the pointing goes in the other direction. If table A hasOne table B, then it can also be said that table B belongsTo table A (except only one B record would be associated with any A record).
In all honesty, I don't think I've ever used this association. This is because if every record in table A only has one record associated in table B, the tables may be able to be combined. Where the use for this association comes in is when you have 1-to-1 relations, but the data may be best kept in different tables for logical or technical reasons. For instance, in the CakePHP manual blog example, every user hasOne profile -- in theory, the tables could be combined, but it probably is easier to keep them apart and accessible through association.
hasMany:
A <- B (multiple)
If table B has a field that references table A, and multiple records in table B can point to the same A record, then table A is said to "hasMany" table B.
Every record in table A says: "I have many records in table B that point to me!"
hasMany is the true sibling to belongsTo. If table A has many B, then table B can be said to belongTo A (and the multiple works, since A has MANY). hasMany and belongsTo are very complimentary if you need to get to a relationship from each side of it.
hasAndBelongsToMany:
A <-> C <-> B (multiple)
If every record in table A can link to multiple references in table B, and every record in table B can be linked to by multiple A records, table A is said to "hasAndBelongToMany" table B.
HABTM is a little more complicated, because it uses a link table. A link table will have at least two fields, one to point to the id of the first table, and another to point to the id of the linked record in the second table. In our movie database example below, since a single movie can have multiple genres, and you can have more than one movie in any given genre, the movie table has many and belongs to the genre table. HABTM associations can go both ways since the link table will work in each direction, so they can be (and often are) defined in both models (as it is done below).
Let's consider a sample application where we're developing a small movie database (an extremely small step-brother to IMDb). This application will be a database of movies categorized by genre with directors and movie reviews. Each movie can be in multiple genres (Action/Horror, Sci-Fi/Thriller, etc), can have one director (we'll ignore multiple directors for now), and have multiple reviews.
We'll start by outlining our models:
- Movie
- belongsTo Director
- hasMany Reviews
- hasAndBelongsToMany Genres
- Director
- hasMany Movies
- Review
- belongsTo Movie
- Genre
- hasAndBelongsToMany Movies
And now some code:
class Movie extends AppModel { var $name = 'Movie' ; var $belongsTo = array( 'Director' => array( 'className' => 'Director' ) ); var $hasMany = array( 'Reviews' => array( 'className' => 'Review' ) ); // We don't need many settings in this association, because we'll stick to Cake's naming conventions var $hasAndBelongsToMany = array( 'Genres' => array( 'className' => 'Genre' ) ); } class Director extends AppModel { var $name = 'Director' ; $hasMany = array( 'Movie' => array( 'className' => 'Movie' ) ); } class Review extends AppModel { var $name = 'Review'; $belongsTo = array( 'Movie' => array( 'className' => 'Movie' ) ); } class Genre extends AppModel { var $name = 'Genre'; // We specify the join table here because Cake would expect the table to be called genres_movies from this side $hasAndBelongsToMany = array( 'Movies' => array( 'className' => 'Movie', 'joinTable' => 'movies_genres' ); }
And for good measure, here's a basic outline of the table structure:
- movies
- id
- title
- release_date
- director_id
- directors
- id
- first_name
- last_name
- reviews
- id
- movie_id
- author_name
- body_text
- genres
- id
- name
- genres_movies (thanks Beertigger!)
- id
- movie_id
- genre_id
Using these models and tables, we can use this line of code in a controller:
$movie = $this->Movie->read(null, $id); //assuming $id contains a movie id...
Will gives us a data structure like this in the $movie variable:
Array (
[id] =>
[title] =>
[release_date] =>
[director_id] =>
[Director] => Array (
[id] =>
[first_name] =>
[last_name] =>
)
[Reviews] => Array (
[0] => Array (
[id] =>
[movie_id] =>
[author_name] =>
)
[1] => Array (
[id] =>
[movie_id] =>
[author_name] =>
)
)
[Genres] => Array (
[0] => Array (
[id] =>
[name] =>
)
[1] => Array (
[id] =>
[name] =>
)
)
)





Anonymous on June 07th 2007
A very helpful article. Especially the tricky hasAndBelongsToMany explanation.
Just one thing, shouldn't it be Director hasMany Movies?
Josh on June 07th 2007
Yep, you're right. Fixed it. Thanks!
Jelka (not verified) on June 26th 2007
I just googled you up and I will bookmark your blog :)
I was searching for ways (if there are any) to deploy cake php on my bluehost page.
I'm new to cakePHP and I was just wondering if there is a way for me to edit my apache config file so that the www root will point to the app/webroot of my cake application (as I tested on my machine this must be done in order for cake to work correctly).
Josh on June 30th 2007
Jelka,
When I use Cake oh bluehost, I usually just make a new subdomain for the site I'm making. If that's not an option, you can use apache's mod_rewrite to have the "base" url point to a subdirectory using the RewriteBase directive. Apache has some great documentation on mod_rewrite available at http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html
Chris (not verified) on July 04th 2007
Joshua... you have just answered all my questions... Thanks, great post.
One thing... Shouldn't we have:
$hasMany = array( 'Movies' => array( 'className' => 'Movie' ) );instead of
$hasMany = array( 'Movie' => array( 'className' => 'Movie' ) );in model director? (I'm not sure...)
Thanks again for great post...
I'll note this on my blog (although it's just starting).
Cheers
Dickey (not verified) on July 19th 2007
This has been most helpful. Here a sql schema I came up with:
Beertigger (not verified) on July 27th 2007
Shouldn't the movies_genres table be genres_movies, following the manual's criteria for placing the referenced tables in alphabetical order?
Josh on August 03rd 2007
Yep, you're right. I never even noticed that little rule. Thanks!
Josh on August 03rd 2007
Glad I could help.
I'm not sure if there is a rule about whether the array keys for associations need to be plural or singular. I typically use singular as you have said, but plural works just fine. You can actually call it anything you want and it works just fine, which I find very useful when I need to associate two table fields with the same table.
kennethd (not verified) on August 12th 2007
Thanks for the helpful post.
I too have been having trouble getting my head around HasOne vs. BelongsTo, and your post helped me make a distinction that I think clarifies the usefulness of HasOne (examples based on my record store project):
belongsTo == many:1 relationship, the current table may have many rows referencing a single foreign key (catalog:label)
hasMany == 1:many relationship, each row in the current table may reference many foreign keys (distro:catalog)
hasOne == 1:1 relationship, here I think the manual's User--Profile example is too simplistic
I have a table called addresses, with a primary key called address_id, which is referenced by several tables: contacts, users, artists, labels, distros, and customer_addresses
Address doesn't belongTo all of those objects, but rather each hasOne address (Customer hasMany CustomerAddress, and CustomerAddress hasOne Address)
and of course,
hasAndBelongsToMany == many:many relationships, which also require an intermediary table, but where the relationship can go either way (catalog:keywords or catalog:tags)
JDS (not verified) on August 14th 2007
Finally, a concise, clear, and specific description of HasOne vs BelongsTo, which, as it turns out, I was constantly getting reversed.
Thanks!
Andrea (not verified) on August 16th 2007
Firstly thanks for this post!
Secondly I have a question :D If I want to implement a Many to Many relation using a table with other fields like:
Users
Groups
Users_Groups
how can I implement this thing?
Thanks!
Ps. sorry for my little English! :D
Lennard (not verified) on August 16th 2007
Thank you so much for sharing this! I was also (and still am) struggling with associations, but after several hours of studying manuals, your blog post and playing around with different models and examples I think it is somewhat clear now ;-)
Josh on August 17th 2007
I accomplished this by using a custom finder query. I will write an article on this eventually, but for now, try to make use of this custom finder query example that I used in an application. The SQL is T-SQL for Microsoft SQL Server, but the concepts are the same for other database engines. Of special note is the {$__cakeID__$} where the foreign key is inserted.
JC (not verified) on August 22nd 2007
How would you handle 'related movies', movies related to other movies?
'Movies' Has and Belongs to Many 'Movies'
Josh on August 23rd 2007
Adrian Gould (not verified) on September 07th 2007
Thanks Joshua for the very well explained blog entry, it is helpful.
I do admit that the arrows do provide a problem for decifering when it comes to the equivalent relational models... so I've taken the step of creating a few diagrams to show the ER equivalents to the models.
I know when I teach Normalisation that I use an arrow along with 1:m style notation to make sure that my students get the differences.
So with this in mind... I've completed the relevant story at http://it.swantafe.wa.edu.au/index.php?option=com_content&task=view&id=1...
All the best, Ady
Adrian Gould (not verified) on September 09th 2007
Joshua
thank you for a great article! Helped me get my head around the concepts. Also I have pointed my students to this URL so they can see the concepts.
I've taken the liberty of creating ER diagrams that represent each of the associations to help my students, as well as myself [it always the way] understand the link between the two concepts. It took me a litle while to make sure I got the arrows the right way round on the two different diagrams.
Anyhow you can find the article at: http://it.swantafe.wa.edu.au/index.php?option=com_content&task=view&id=1...
All the best
Adrian
Lecturer in IT, Swan TAFE, PERTH, Western Australia
Charlie (not verified) on September 12th 2007
Hi,
I want to use the belongsTo feature of cake, but in both of my used tables I have the field 'name'. How can I make use of 'Country.name AS cname' feature of the queries without having to write my own queries?
Josh on September 17th 2007
If tables `states` and `countries` both have a `name` field, and states belongsTo countries, then your returned array might look like this (slightly different depending on how and where you execute the query):
Jeremy (not verified) on September 27th 2007
This was exactly the explanation I had been looking for, for days. Thanks for making it so clear! They should take this and put it in the manual.
Kostas (not verified) on October 03rd 2007
Hey Joshua nice work!
In your examples After having set all the HABTM associations in the appropriate models,how can you retrieve the 1. id field from the following table?
genres_moview
1. id
2. movie_id
3. genre_id
I think that the only solution is by setting a custom SQL (findQuery)
Any ideas ?
Josh on October 05th 2007
I will probably write an article about this technique, but I need to look into some recent changes that have been generating some noise in CakePHP community about HABTM associations first.
One option, of course, is to create a model for the link table and perform a find* on that model once you have the information to build the conditions for the find. If I understand what you're asking, you'd like to retrieve additional information from the link table with the other data being pulled by the find call on one of the related models.
What you want to do is perfectly doable, but it's not the most straight-forward thing. You're correct that it requires a custom query, but with some thought, this isn't so difficult to rule it out.
In my first Cake project, I was developing a little app that interfaced with our MSSQL system to pull data about faculty members and details about their credit load, student count, etc to process overall "workload." There was of course a table (view actually) that had a row for each faculty member, but there was also a table that listed all the possible non-course activities a professor could engage in (coaching, chairing a department, etc). So, there was a HABTM relationship between faculty and activities.
The catch was that each activity that a professor had also had a student count associated with it -- data that was best stored along with the link itself in the association link table. It took a lot of digging and eventually trudging through the source yielded the most reliable answers. Here's the custom query I used to accomplish this:
Note the {$__cakeID__$} token -- it's an identifier that cake will substitute with the ID of the model being retrieved. I'll be honest and note that I don't have a 100% understanding of how cake handles this -- but that's part of the magic of cake: understanding the inner workings is helpful and powerful, but not always necessary :).
Hope that helps!
Miko (not verified) on October 05th 2007
Before reading your article, I never really understood the difference between belongsTo and hasOne! Good stuff!
Conficio (not verified) on October 05th 2007
Hi Josh,
can you extend your article or write another one that explains the consequences of the various relations in the case of deleting an object.
For example should "hasMany" implicate owner ship, saying if post has many comments than if a particular post is deleted all related comments should be deleted too.
K<o>
Prakash (not verified) on October 14th 2007
This is an awesome explanation! I was able to build a small movie database with grouping just by understanding what everything meant! I have a somewhat stupid question though:
Genre > Director > Movie
Everything works the way I want it to for my movie collection, but how do i display the genre on the movie page using cake? Right now scaffolding automatically links director which is fine, but I'd like to see the genre as well. Sorry if this is going a little beyond what you're trying to do here, any help would be appreciated. Thanks again!
fatigue (not verified) on October 16th 2007
Hi Joshua. Thank you for your great post. By the way, there is a little a bug in your code.
On the class definition of "director", "genre" and "review", there should be "var" before the $belongsTo, $hasMany and $hasAndBelongsToMany (like as var $belongsTo etc.).
Also, I have a question for you: If a model belongs to different models (more than one), how can we add our model code? For example, we shall add a "Production Firm" table for Movies. Than, every movies shall be belongs to a "Production Firm" and a "Director" etc.
Josh on November 18th 2007
To add more than one association of a given nature, it's simply a matter of adding another element to the respective association definition array.
Thanks for the note about the var... I actually think you can leave 'var' out and PHP is okay with it (though I always use var).
Josh on November 18th 2007
If you need to do association lookups in both directions, you should define a given associations from each end of the relationship.
If model A belongsTo model B, then model B can also hasOne model A, etc.
Josh on November 18th 2007
That consideration will be largely dependent on how your application is structured. In the example of a movie database there are no examples where deleting one record would mandate the deletion of one of its related records.
However, if your application has content items with associated comments, deletion of an item would logically include disposing of the comment records.
There is no magic rule here, just logic. If you think procedurally and logically enough to be programming web applications, you can determine when a record needs to be deleted, I'd say. If I were to look for a "rule of thumb," I'd say it's to delete information when it loses it's potential to be used again.
Greg (not verified) on November 27th 2007
Fantastic article!
I've been playing with Cake for a couple weeks and my structures just weren't working. I didn't realize that you needed to put reciprocal association in both models. Your great example really showed me where I was making my mistakes.
Thanks
Anonymous (not verified) on December 13th 2007
I tried to run the same thing but having a strange problem.
I'm asked to remove the s at the end of the movies_id colunm in the reviews table.
Cake1.2 naturaly puts need s so why in this case the s is not needed.
this is my model
CREATE TABLE categories (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
name TEXT NULL,
PRIMARY KEY(id)
);
CREATE TABLE categories_places (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
categories_id INTEGER UNSIGNED NOT NULL,
places_id INTEGER UNSIGNED NOT NULL,
PRIMARY KEY(id),
INDEX categories_places_FKIndex1(categories_id),
INDEX categories_places_FKIndex2(places_id)
);
CREATE TABLE categoryinfos (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
categories_id INTEGER UNSIGNED NOT NULL,
name TEXT NULL,
lang VARCHAR(50) NULL,
PRIMARY KEY(id),
INDEX categoryinfos_FKIndex1(categories_id)
);
CREATE TABLE placeimageinfos (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
placeimages_id INTEGER UNSIGNED NOT NULL,
name TEXT NULL,
lang VARCHAR(50) NULL,
PRIMARY KEY(id),
INDEX placeimageinfos_FKIndex1(placeimages_id)
);
CREATE TABLE placeimages (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
places_id INTEGER UNSIGNED NOT NULL,
name TEXT NULL,
PRIMARY KEY(id),
INDEX placeimages_FKIndex1(places_id)
);
CREATE TABLE placeinfos (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
places_id INTEGER UNSIGNED NOT NULL,
name TEXT NULL,
lang VARCHAR(50) NULL,
PRIMARY KEY(id),
INDEX placeinfos_FKIndex1(places_id)
);
CREATE TABLE places (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
name TEXT NULL,
PRIMARY KEY(id)
);
What I want to do is I have some places that belong to some categories(a place can belong to many categories).And the categories and the places have language information according to language
I want to retrieves a category with all the places that belong to it with the language information that is passed.
How can I write that with cake HABTM
Josh on December 16th 2007
1) You don't put the 's' on 'movie' in the field name, since the field will point to only one movie, it is singular. So, movie_id.
2) Forming an HABTM relationship between places and categories isn't a problem, and you already have the categories_places table defined (though note that you're using plurals in your field names again!). Just define the HABTM in the direction which you plan to retrieve the data: If you want to get all places when you know the category, you define the HABTM in the category model. If you want the categories for a given place, you define HABTM in the places model. If you want to be able to go both directions, define the relationship in both models.
Anonymous (not verified) on December 18th 2007
Hey Joshua,
I've read through the cakephp manual and the cakephp tutorial on IBM - but never understood the difference between belongsTo and hasOne. I eventually thought, I could use them interchangeably.
Really appreciate the time you took in clearly explaining the concepts.
Awesome job.
Thanks Again
Lance (not verified) on December 19th 2007
Thanks for the tutorial, it's getting clearer for me. I am trying to build a small application and have been hacking to do what associations do naturally, so now I am trying to use associations to achieve it cleaner and more easily.
Thanks!
rav (not verified) on December 24th 2007
Hi, I have 2 questions.
Firstly I have a database schema and I'm rather confused about how cake handles associations.
Does cakes implementation of the associations mean that the foreign key relationships don't have to be defined in the database?
Looking at Anon's database schema above, he/she has created a database schema with no foreign keys. Does Cake require the database design to be ridden of Foreign Key? And if not how does it deal with Foreign Key settings such as "On Update" and "On Delete" when Cake sends calls like save() and delete() to the database.
This is my one major road blocker at the moment. I would generally prefer to implement my db with all the necessary associations. It makes it functional across different applications since it is itself an individual tier.
Any idea what I should do?
albert (not verified) on December 29th 2007
Hello, nice tutorial but i have a problem because if i do this in a controller :
$this->Movie->findAll();
i will have a big table with all attributes of all tables but if i want only some attributes i can't filter the attributes of the associations tables. somebody know how i can do ?
Dave (not verified) on December 31st 2007
Thanks for the good explanation. Can you expand on how one would define child models in an add view? I have a case where there will always be ten child models for every parent. When a new parent has been created, I'd like to have the ten child models fields defined on the view.
Thanks again!
knoodrake (not verified) on January 08th 2008
Hi. a Very good tutorial, and many useful comments below !
First, please excuse my English since I'm French.
I've a problem with HABTM ( hasAndBelongsToMany ) relations.
like in the cake's manual examples, i have 3 things: Posts, Tags, and a relation table for them.
Assuming that a post haveAndBelongsToMany tags, i edited the Post Model and all works perfectly while i just want to retrieve data, but in the other hand, I'm being crazy by trying to save a new Post with tags ( some are new, other already exists ) and the relation between them.
At this point, I've few problems:
- How to save multiple (new or not) tags all at once.
Anyhow, thanx a lot for this tutorial !
Anonymous (not verified) on January 31st 2008
Can you please post, how the related-table (foreign-keys) look like for this example?
Ricardo (not verified) on March 07th 2008
Just wanna say thanks for the great explanation :). Im doing some catalogue for personal use and i didnt know how to do the models part on CakePhp, now is all clear to me :).
Anonymous (not verified) on March 14th 2008
Hi, I've followed the steps described but the controllor is not generating the associations when querying. Please see details below:
DB Structure:
CREATE TABLE categories (
id INT(10) NOT NULL AUTO_INCREMENT,
title VARCHAR( 100 ) NOT NULL,
created DATETIME NOT NULL ,
modified DATETIME NOT NULL,
PRIMARY KEY(id)
) ENGINE=INNODB;
CREATE TABLE blogs (
id INT(10) NOT NULL AUTO_INCREMENT,
category_id INT(10) NOT NULL,
title VARCHAR(100) NOT NULL,
body TEXT NOT NULL,
allow_comments INT(1) DEFAULT '0',
created DATETIME NOT NULL ,
modified DATETIME NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY (category_id) REFERENCES categories(id)
) ENGINE=INNODB;
CREATE TABLE comments (
id INT(10) NOT NULL AUTO_INCREMENT,
blog_id INT(10) NOT NULL,
body TEXT NOT NULL ,
approved INT(1) DEFAULT '0',
created DATETIME NOT NULL ,
modified DATETIME NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY (blog_id) REFERENCES blogs(id)
) ENGINE=INNODB;
Models:
class Category extends AppModel
{
var $name = 'Category';
//Relationships
var $hasMany = array(
'Blog' => array(
'className' => 'Blog',
'foreignKey' => 'category_id',
'order' => 'Blog.created DESC',
'dependent'=> true
)
);
//Rules
var $validate = array(
'title' => array(
'rule' => array('minLength', 1)
)
);
}
class Blog extends AppModel
{
var $name = 'Blog';
//Relationships
var $belongsTo = 'Category';
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'conditions' => 'Comment.approved = 1',
'order' => 'Comment.created DESC'
)
);
//Rules
var $validate = array(
'title' => array(
'rule' => array('minLength', 1)
),
'body' => array(
'rule' => array('minLength', 1)
)
);
}
class Comment extends AppModel
{
var $name = 'Comment';
//Relationships
var $belongsTo = 'Blog';
//Rules
var $validate = array(
'body' => array(
'rule' => array('minLength', 1)
)
);
}
Controller:
class HomeController extends AppController {
//mandatory
var $name = 'Home';
//layout used on view
var $layout = 'blog';
//Models used in the controller
var $uses = array('Categories','Blogs');
//Helpers used in the view;
var $helpers = array('Form','Html','Javascript','Ajax','Date');
//Main method
function index() {
//get all categories
$this->set('cats', $this->Categories->findAll());
}
}
----------
Even though everything seems fine, $cats variable does not contains associated nodes! (it should containg all the related blog elements per category!):
Array
(
[0] => Array
(
[Categories] => Array
(
[id] => 2
[title] => Other Info
[created] => 2008-03-12 00:27:36
[modified] => 2008-03-12 00:27:36
)
)
[1] => Array
(
[Categories] => Array
(
[id] => 3
[title] => Oracle SOA Suite 10.1.3.3
[created] => 2008-03-12 00:27:44
[modified] => 2008-03-12 00:27:44
)
)
[2] => Array
(
[Categories] => Array
(
[id] => 4
[title] => SOA Solution Architecture
[created] => 2008-03-12 00:27:53
[modified] => 2008-03-12 00:27:53
)
)
)
Alex Medeiros (not verified) on March 24th 2008
I have a problem in my cake aplication, i have a associate table which associate 'pages' and 'module', but in this table i have other columm 'position'. When I save, $this->date dont send de attribute position.
When cake save, it save only 'page_id' and 'module_id'.
how i insert this data with 'position'?
Josh on March 29th 2008
I haven't done any Cake code in quite a while, but what you're trying to do sounds like you may need a custom query to store the HABTM relationship. If you do some searching on the Cake Google Group you should be able to find what you're looking for. You can also post there, as the community is filled with some very intelligent, helpful people.
Check this thread: http://groups.google.com/group/cake-php/web/frequent-discussions
Post new comment