CakePHP alias breaks HABTM Model - php

Consider the following HABTM relation in CakePHP 2.2.3:
class User extends AppModel
{
public $hasAndBelongsToMany = array(
'Role' => array(
'className' => 'Role',
'joinTable' => 'roles_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'role_id',
)
);
}
This works fine, but when using an alias like VeryUniqueAlias instead of Role and changing the UsersController accordingly, the m:n relation is not persisted in the database (the data passed to save() in the controller are equivalent).
This does not work:
class User extends AppModel
{
public $hasAndBelongsToMany = array(
'VeryUniqueAlias' => array(
'className' => 'Role',
'joinTable' => 'roles_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'role_id',
)
);
}
This is awkward, since the the CakePHP docs state that it should work.
Any idea why it's not working for me? Did I miss something?

Use the 'with' key to define the name of the model for the join table. In your case:
public $hasAndBelongsToMany = array(
'VeryUniqueAlias' => array(
'className' => 'Role',
'joinTable' => 'roles_users',
'with' => 'RolesUser', // first model pluralized
'foreignKey' => 'user_id',
'associationForeignKey' => 'role_id',
)
);

Related

CakePHP not binding model automatically

CakePHP 2.8.3 is not binding the model automatically.
Model :
<?php
class Item extends AppModel
{
public $name = 'Item';
public $belongsTo = array(
'Cat' => array(
'className' => 'Cat',
'foreignKey' => 'cat_id',
),
);
}
The above Model is not working.
However when I Bind Model in controller. It works fine.
$this->Item->bindModel(array(
'belongsTo' => array(
'Cat' => array(
'foreignKey' => 'cat_id',
))));
What could be the cause ?

how to define 2 habtm Association in one model in cakephp

i have a model that have 2 habtm association.
my models are: 'Course', 'Teacher' and 'Student.
course hasAndBelongsToMany Teacher and hasAndBelongsToMany Student.
when i coding like this:
public $hasAndBelongsToMany = 'Student';
public $hasAndBelongsToMany = 'Teacher';
Or:
public $hasAndBelongsToMany = array(
'Student' => array(
'className' => 'Student',
'joinTable' => 'courses_students',
'foreignKey'=> 'course_id',
'associationForeignKey' => 'student_id'
),
'Teacher' => array(
'className' => 'Teacher',
'joinTable' => 'courses_teachers',
'foreignKey'=> 'course_id',
'associationForeignKey' => 'teacher_id'
)
);
i see internal error
how can i code this?
Thanks
"Cannot redeclare class Course"
says it all: you probably have a copy-and-paste-error.
You declare the class wrong in your Teacher.php (should be Teacher not Course).

CakePHP JOINS Query

I was following a tutorial about permissions instead CakePHP.
I don't understand how this model (query) works.
Can anybody explain me how this query works.. I can't find what this variable hasAndBelongsToMany exactly does.
<?php
class Group extends Appmodel {
var $name = 'Group';
var $useTable 'groups';
var $hasAndBelongsToMany = array(
'Permission' => array('className' => 'Permission',
'joinTable' => 'groups_permissions',
'foreignKey' => 'group_id',
'associationForeignKey' => 'permission_id',
'unique' => true
)
'User' => array('className' => 'User',
'joinTable' => 'groups_users',
'foreignKey' => 'group_id',
'associationForeignKey' => 'user_id',
'unique' => true
),
);
}
First of all it is not a query. it is a declaration of relation of the model to other models.
$hasAndBelongsToMany means that every record in your database is associated with many records of another table, and the many records from other table can be associated with the current record as well.
for example Book can have many authors, and an authors can have many books. so it can be related as hasAndBelongsToMany.
in your case Group has many users, and users have many groups. same for permissions.

problem with counterCache of cakePHP

I have in a video sharing website project these models :
class Video extends AppModel {
var $name = 'Video';
var $hasAndBelongsToMany = array(
'Tag' => array(
'className' => 'Tag',
'joinTable' => 'videos_tags',
'foreignKey' => 'video_id',
'associationForeignKey' => 'tag_id',
'unique' => true,
)
);
}
class Tag extends AppModel {
var $name = 'Tag';
var $hasAndBelongsToMany = array(
'Video' => array(
'className' => 'Video',
'joinTable' => 'videos_tags',
'foreignKey' => 'tag_id',
'associationForeignKey' => 'video_id',
'unique' => true,
)
);
}
class VideosTag extends AppModel {
var $name = 'VideosTag';
var $belongsTo = array(
'Video' => array(
'className' => 'Video',
'foreignKey' => 'video_id',
),
'Tag' => array(
'className' => 'Tag',
'foreignKey' => 'tag_id',
'conditions' => '',
'counterCache' => 'videos_tag_counter'
)
);
}
The counterCache for tags is not working. I don't know why and when I tried to add a beforeSave() callback to videosTag model I found that it doesn't execute when a video get saved (and this video has tags and i find them in the database so how the relation videosTags is saved ? ) !!! can any body explain why this is happening.
Saving a Video with data like this:
array(
'Video' => array(
...
),
'Tag' => array(
'Tag' => array(
...
),
),
);
on the Video model will not trigger a beforeSave callback on the VideosTag model because Cake handles HABTM data without requiring (or even using) the join/with/through model.
There is no built in functionality for what you are trying to achieve, as far as I am aware.
Check out Counter Cache behavior for HABTM relations, might do what you need

How do I create a Unary association in CakePhp?

Is there a shortcut for creating Unary associations in Cake?
For example, a user is a friend of another user. I'm pretty sure it's going to violate cake's conventions if I try it the hard way and code the associations myself.
Cake has HABTM:
var $hasAndBelongsToMany = array(
'User' =>
array(
'className' => 'User',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
Will this work? A user model assoc to another user model.
Update:
How do I save the data now?
$this->data["Friend"] = $request["Requester"];
$this->data["Admirer"] = $request["Requestee"];
$this->Friend->create();
$this->Friend->save($this->data);
$request["Requester"] and $request["Requestee"] both hold objects of type User.
The HABTM rel is defined in the User model
var $hasAndBelongsToMany = array(
'Friend' => array(
'className' => 'Friend',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'id'
),
'Admirer'=>array(
'className'=>'Friend',
'joinTable'=>'friends',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'id',
)
);
All that happens is the $data->["Friend"]'s id is stored in the id column of the friends table
Here is a solution I use in an example application
Two tables are needed, users and followers. The important fields are User->id, Follower->user_id, Follower->friend_id.
I hope this snippet helps.
&lt?php
class User extends AppModel {
public $useTable='users';
public $hasAndBelongsToMany=array(
'Friend'=>array(
'className'=>'User',
'joinTable'=>'followers',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
),
'Admirer'=>array(
'className'=>'User',
'joinTable'=>'followers',
'associationForeignKey' => 'friend_id',
'foreignKey' => 'user_id',
),
);
}
-teh
Bjorn,
he is asking about User habtm User...
your join table should be users_users and the relation should look like this
var $hasAndBelongsToMany = array(
'Friend' =>
array(
'className' => 'UserUser',
'joinTable' => 'users_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
i think that should do the trick
In CakePHP there are several variables in your model available to do that, like $hasMany, $belongsTo and $hasAndBelongsToMany. Please read the Cookbook for further explaination.. http://book.cakephp.org/view/78/Associations-Linking-Models-Together .
In your example, I think you need HABTM.

Categories