c. 2006

Houston, TX

MySQL Data Structure for your CakePHP Website – Associations and Building the MVC

February 10, 2009

In MySQL Data Structure for your CakePHP Website – Building Associations, we discussed the basics of building associations and the differences between belongsTo, hasOne, hasMany, and hasAndBelongsToMany model associations. This basic setup in our models could not have been done easily without setting up our databases correctly which we discussed in MySQL Data Structure for your CakePHP Website – Site Planning and further in the previously mentioned article. But we are not quite ready to start setting up our models, views and controllers. We still have some work to do on our associations.

Our setup was to allow essentially five “pages” for our initial blog: Users, Categories, Posts, Comments and Meta tags (remember, we do not need to make our States visible as they should not require adding, editing or deleting once input into the database. Any alterations can be done in the backend via PHPMyAdmin or another database program). When our models are setup with the appropriate associations, we should have something like the following:

File: app/models/user.php

class User extends AppModel {

	var $name = 'User';
	var $hasMany = array( 'Post' , 'Comment' );

}

Looks very simple, doesn’t it? Notice in our hasMany array we’ve passed as values the names of our Models; a singular capitalized class name. When you look at an association from this aspect it’s likely easier to understand than by looking at database tables. It’s also easier to understand without going into the details of every single possible key that is attached with each association. Which is why we’ve kept it simple for now.

Hopefully by now you’ve noticed we are missing something. We forgot to associate User with State. We discussed earlier, though, that User does not hasMany State. Rather, User hasOne State. Some make the mistake of trying to create a complex array of hasOne and hasMany. It’s just as simple.

var $hasOne = 'State';

You should still hopefully notice something is different – missing. Why didn’t we declare hasOne an array? Simply, we didn’t need to. We declared hasMany an array because User hasMany association has different tables to pull information from. CakePHP mandates in this situation we load the classNames into arrays. However, because User only requires a hasOne association with one table, we can simply make hasOne a string.

Fatal error: Class ‘State’ not found in …cake\libs\class_registry.php on line 128

You may notice the above error message when building your application. This error likely tells you that you have not properly declared all of your classes. Before attempting to review your website to see if it is functioning remember that we have yet to start testing and debugging. We are merely laying the groundwork.

We then have our State model to worry about. Thankfully, this is very easy also. We set our User model up to hasOne State. So, quite simply, in our State model, we would assign a belongsTo association. That would look like this:

File: app/models/state.php

class State extends AppModel {

	var $name = 'State';
	var $belongsTo = 'User';

}

Again, notice we only passed our var $belongsTo a string value. If State belongsTo more than one class we would pass an array much like we did for User hasMany Post and User hasMany Comment. Do not get confused into thinking whether you pass a string or an array depends on the type of association. It is simply based upon the number of values you wish to pass to one particular association.

Now that we have our User and State set up we can start on Category and work our way down. Category hasMany Post. We don’t want to assign Comment to a Category, do we? Only if we wished to display every single Comment for every single Post that was related to Category. That makes no sense. We could assign User to Category. That would be logical. After all, who created Category? But we didn’t set that up with our tables and we won’t worry about it now. Could we assign Meta? Absolutely and that would make perfect sense as well. After all, Wordpress allows you to view posts by categories. Wouldn’t it be fitting to assign custom meta titles and meta keywords to your categories pages?

Download the source code at Box.net

Pages: 1 2

Drop a note!

smooth_writer February 11, 2009 at 7:50 am

Seeing the mysql table results at the bottom doesn’t mean you’ve hooked everything up right. you need to input some data and have it displaying in the users model to know that its actually working. you should be able to see all of your data from all of the tables. especially if your not passing additional values through the associations

Reply

varelse February 11, 2009 at 11:45 am

the fatal error you showed also could mean you haven’t named your controller file correctly. controller and model files should have php extensions. not ctp extensions that views have

Reply

timtrice February 11, 2009 at 12:49 pm

actually if you renamed your controller or model file incorrectly, it generates an error from within Cake itself. Fatal error’s are generated by PHP and stop execution of the script. If I remember correctly, CakePHP tells you that there no controller file exists and instructs you how to create it. All within your Template. I don’t think an error is generated for a missing model. But I could be wrong.

You are correct about the file extensions, though

Reply