php - CakePHP HATBM not working
I'm starting a cakephp app, I've never used it in real world so I'm a bit confused how HABTM works, even though I read the documentation I couldn't get even the
$this->User->Subscription and didn't see any extra object dumped
What I want is to create a HATBM between users and subscriptions
so I created three tables (users,subscriptions,users_subscribers)
Then in my
User.php model I did this
var $hasAndBelongsToMany = array( 'Subscription' => array('className'=>'Subscription', 'joinTable' => 'users_subscribers', 'foreignKey' => 'user_id', 'associationForeignKey' => 'subscription_id', 'unique' => true, ) );
var $hasAndBelongsToMany = array( 'User'=>array('className'=>'User', 'joinTable' => 'users_subscribers', 'foreignKey' => 'subscription_id', 'associationForeignKey' => 'user_id', 'unique' => true));
Even with the tags example and following it, I cannot get the relation set, I also added the line
<?php echo $this->element('sql_dump'); ?> to see if its running which it isn't...
Could anyone guide me how exactly you get HATBM to work, what else do I need to verify?
Full code: pages_controller.php http://sao.pastebin.com/PWQMhE2z
User model: http://sao.pastebin.com/PWqwAj1v
Subscription model: http://sao.pastebin.com/MfVFR4Kw
subscriptions SCHEMA: http://sao.pastebin.com/mLRcEp1c
User SCHEMA: http://sao.pastebin.com/UeTRHh3u
users_subscriptions SCHEMA: http://sao.pastebin.com/4UeSDZte
The simplest and fastest way to get this working is by following CakePHP's rule of configuration over customization.
This means following the CakePHP conventions unless you have a very good reason not to.
I'd strongly recommend starting with a basic setup that you know works, and then modifying that if you need to. Here's a quick and easy way to get up and running.
The Database Tables
Start with three database tables: users, subscriptions and subscriptions_users. The schemas you already have are ok, but I'd make a couple modifications to make sure things go smoothly:
titlecolumn to the
userstable. Either that, or you'll have to add the
$displayFieldproperty to your User model. If you don't do this you'll miss out on some of the "automagic" that CakePHP provides. More info on $displayField
subscriptions_users. This is the CakePHP convention and there's no reason not to save yourself the time and worry of following it. :-)
Note that there aren't any keys defined. From the CakePHP manual: "To avoid any issues - don't define a combined primary key for these two fields, if your application requires it you can define a unique index."
Try to keep your code clean. There are a lot of sensible defaults implemented in CakePHP and there's no point in defining them when they're already defined.
The following models should work for you:
Pretty simple. Just be sure your model files are named correctly: user.php and subscription.php, all lowercase.
Also, note that you don't have to set any of the relationship options (
joinTable, etc.) unless they need to be something besides the default. Ninety percent of the time the defaults should serve you just fine.
You should be up and running now. You can make sure the model objects are being loaded and are accessible in your controllers like this:
The output of /users and /subscriptions should both be
You can see the full models by doing
If you delete a single record using, for example,
$this->User->delete($user_id), all the records in the join table with that user ID will automatically be deleted as well.
If you want to delete a single record from a HABTM join table, without deleting the records that it links to, in effect, "unjoining" the two records, you can do it through the SubscriptionsUser model. This is a model that is created on the fly whenever there's a HABTM relationship.
See here for an example: CakePHP hasAndBelongsToMany (HABTM) Delete Joining Record
I did a test app with a basic schema and I get all the relations right. I suspect your woes have to do with the fact that you did
$uses = array('User', 'Subscription');Why don't you try with
$uses = $uses = array('User');and then try
You also need to define the same HABTM relation in your
Subscription.phpmodel. If I recall correctly, CakePHP internally fetches some of the required information from the other side's HABTM configuration.
I always use two "hasMany" relations and one "belongsTo" relation to get the HABTM effect in CakePHP with more control.
User model (user.php)
Subscription model (subscription.php)
UserSubscription model (user_subscription.php)
pages/home action (pages_controller.php)