CakePHP – model for HABTM join table

Do you have problems with relations in a CakePHP model? Did you define a relation like belongsTo in your model and somehow it’s not visible when you create query with it? Well, it’s possible that you created a model which is a join table for HABTM relation. Here is what I found:

Imagine that you have 2 tables with relation HABTM. Posts has and belongs to many (HABTM) categories. The tables will be:

posts -< posts_categories >- categories

In the normal case scenario you should have Models only for posts and categories tables and they both will have $hasAndBelongsToMany variable explaining the relation.

The problem comes when you create a model for posts_categories table an try to add some relations – at least most common

var $belongsTo = array('Category', 'Post');

and if you make a query like this:

$this-&gt;PostsCategory-&gt;find('all', array('contain'=&gt;'Post'));

you will be surprised when you see an error saying Model $Post is not available in PostsCategory class. The reason – CakePHP created a virtual model for the join table and it override the model which I created (I haven’t digg into the core but I suppose that this is the case). If you delete the HABTM relation both from Post and Category models, the belongsTo relation for PostsCategory will appear properly.

My current solution is to create a separate model with a different name like PostsCategories which should be used for the queries like above.

The case is hypothetic, but I hope this will help to someone with the same problem.

2 thoughts on “CakePHP – model for HABTM join table

  1. majna

    define ‘with’ => PostsCategory
    it’s in docs:
    http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

    with: Defines the name of the model for the join table. By default CakePHP will auto-create a model for you. Using the example above it would be called RecipesTag. By using this key you can override this default name. The join table model can be used just like any “regular” model to access the join table directly.

Leave a Reply

Your email address will not be published. Required fields are marked *