Models association help in CakePHP - cakephp

I'm currently developing a project using CakePHP where users can create projects. Each project has only one administrator user, but other users should be able to "view" the project. How should I create this "view" option to users?
I've already done the following model associations:
[Users Model] hasMany [Projects] (by the time each user can have many projects).
I'm kinda perplexed now and I don't know exactly what additional model association i should create :/ I think a belongsTo or a HasAndBelongsToMany but i'm not sure :/ Can you help me out here?
thank you in advance!

You need to have 3 database tables
users
projects - This table needs to have a column (administrator) which contains the user_id representing the user who is the administrator
usersprojects - This table is cross reference table between the users and projects representing the members of a project
CakePHP Models
User
public $useTable = 'users';
public $hasMany = array(
'ProjectAsAdmin' => array(
'className' => 'Project')
);
public $hasAndBelongsToMany = array(
'ProjectAsMember' => array(
'className' => 'Project')
);
Project
public $useTable = 'projects';
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'User')
);
public $belongsTo = array(
'Administrator' => array(
'className' => 'User',
'foreignKey' => 'administrator'
)
);

Related

CakePHP Join virtualField as displayField

I'm trying to do one of two things, use a virtual field from a model as the display field in my join model, or use the virtual field as the display in a find('list') on my join model.
Here's the current layout:
MODELS
<?php
class Participant extends AppModel {
public $hasMany = array('Registration');
public $virtualFields = array(
'full_name' => 'CONCAT(last_name, ", ", first_name)'
);
public $displayField = 'full_name';
}
-----
class Contest extends AppModel {
public $hasMany = array('Registration');
}
-----
class Registration extends AppModel {
public $belongsTo = array('Participant', 'Contest');
public $hasMany = array('Assignment');
}
?>
Tables are as follows:
participants contests registrations
------------ --------- --------------
id id id
first_name name contest_id
last_name participant_id
In my contests controller I'm trying to develop a list to be viewed as checkboxes in the view.
Here is the excerpt from my contests controller:
$this->loadModel('Registration');
$this->set('registrations', $this->Registration->find(
'list',
array(
'conditions' => array('contest_id' => $contestId),
'recursive' => 1
)
)
);
//$contestId is defined previously, and I have verified such.
This all actually runs fine as it is, and in the view will display a column of checkboxes with the registration_id as the label next to the checkbox.
I would like to get a full_name as is defined in the Participant model to be the displayField of the Registration model. I've been searching and can't quite seem to find a good way of doing that. I hope I have been descriptive enough, and please let me know if you have any questions and I'll try to explain better. Thank you.
edit: I'm using CakePHP 2.4.
try to add the 'fields' parameter
$this->loadModel('Registration');
$this->set('registrations', $this->Registration->find(
'list',
array(
'fields' => array('Registration.id', 'Participant.full_name'),
'conditions' => array('contest_id' => $contestId),
'recursive' => 1
)
));
edit: apparently cake does not place virtual fields of associated models when using find() with 'fields' options.
So you have to build your array by yourself, hoping your models use the containable behavior
$registrations = $this->Registration->find(
'all',
array(
'contain' => array(
'Participant' => array('full_name')
),
'conditions' => array('contest_id' => $contestId),
)
);
$registrations = Hash::combine($registrations, '{n}.Registration.id', '{n}.Participant.full_name');
$this->set('registrations', $registrations);

CakePHP HABTM relationship table joins

I have a 'patient_cases' table with a HABTM relationship with a 'procedures' table. This 'procedures' tables has a many to one relationship with 'consultants' table, which then has a many to one relationship with 'specialties' table.
The relationships are working fine and using cakephp debug tool bar i can see everything is coming through correctly when i look at 'patient_cases' index page, however i'm only getting consultant_id and specialty_id rather than all of the fields with that associated model.
which is what should be happening i believe -
In CakePHP some associations (belongsTo and hasOne) performs automatic
joins to retrieve data, so you can issue queries to retrieve models
based on data in the related one.
But this is not the case with hasMany and hasAndBelongsToMany
associations.
I want to be able to get the consultant name from 'consultants' table using procedures.consultant_id and get the specialty name from 'specialties' using consultant.specialty_id.
I have tried playing about with some table joins but with no success,
class PatientCase extends AppModel {
public $hasAndBelongsToMany = array(
'Procedure' => array(
'className' => 'Procedure',
'joinTable' => 'patient_cases_procedures',
'foreignKey' => 'patient_case_id',
'associationForeignKey' => 'procedure_id',
'unique' => true
)
);
}
class Procedure extends AppModel {
public $belongsTo = array(
'Consultant' => array(
'className' => 'Consultant'
)
);
}
class Consultant extends AppModel {
public $belongsTo = array(
'Specialty' => array(
'className' => 'Specialty',
'conditions' => array('Specialty.active' => 1)
)
);
public $hasMany = array(
'Procedure'
);
}
class Specialty extends AppModel {
public $hasOne = array(
'Consultant'
);
);
}
$this->set('patientCases', $this->PatientCase->find('all'));
Returns everything i need, each model array is returned (other relationships not mentioned here), however the model array 'Consultant' is not returned, which also means i can not get the 'Specialty' data which is linked to the 'Consultant' model
EDIT
I have managed to get the data i need by using this in my PatientCasesController
$this->set('patientCases', $this->PatientCase->find('all'));
$this->set('patientCaseProcedures', $this->PatientCase->Procedure->find('all'));
However, ideally i want to return everything in the one 'patientCases', is this possible?
EDIT
I have solved the problem using the recursive function
$this->PatientCase->recursive = 3;
$this->set('patientCases', $this->PatientCase->find('all'));

List comments for picture with username cakePhp

I have a problem with my comments.
I have User model:
public $hasMany = array('Photo','Comment');
Comment model:
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
),
'Photo'=>array(
'className'=>'Photo',
'foreignKey'=>'photo_id'
)
);
and Photo Model
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
)
);
public $hasMany = array(
'Comment'=>array(
'className'=>'Comment',
'foreignKey'=>'photo_id'
)
);
When I read data of a photo I got:
'Photo' => array -> info about photo which is ok for me
'User' => array -> info about user ok for me
'Comment' => array -> all comments but only with id of users.
How can I connet comments with users to get username related with comment while retrieving data about photo?
You need to call $this->recursive = 2 before you call find(), that will fetch all associations of every object returned by your query. Alternatively you can set the $recursive variable inside any of your models.
The different types of recursion are as follows:
-1 Cake fetches Photo data only, no joins.
0 Cake fetches Photo data and its domain
1 Cake fetches a Photo, its domain and its associated Comments
2 Cake fetches a Photo, its domain, its associated Comments, and the
Comments’ associated Users
I also suggest considering Containable since you have complete control of all the data that is returned, down to specifying each field in any association
The photo model:
<?php
class Photo extends AppModel {
public $actsAs = array('Containable');
}
And your find method will look like this:
<?php
$this->Photo->find('all', array(
'contain' => array(
'User',
'Comment' => array(
'User' = array(
'fields' => array('username')
),
'conditions' => array(
'Comment.erased' => 0
)
))
'conditions' => array(
'Photo.id' => $id
)));

Add a friend feature in CakePHP

I need a simple add a friend feature in my application, through some research, I would need a join table linking back to users table ? something like this: (I already have a users table)
Users-Friendships-Users
Can anyone give more details about this?
The friendships table should have following columns:
id Integer
user_from (the user who requested friendship)
user_to (the user who accepted friendship)
created (optional to track when your friendship started)
Then you need to create proper Model relation.
class User extends AppModel {
...
var $hasMany = array(
'UserFrom'=>array(
'className'=>'Friendship',
'foreignKey'=>'user_from'
),
'UserTo'=>array(
'className'=>'Friendship',
'foreignKey'=>'user_to'
)
);
var $hasAndBelongsToMany = array(
'Friendship' => array(
'className' => 'User',
'joinTable' => 'friendships',
'foreignKey' => 'user_from',
'associationForeignKey' => 'user_to'
);
...
}
class Friendship extends AppModel {
...
var $belongsTo = array(
'UserFrom'=>array(
'className'=>'User',
'foreignKey'=>'user_from'
),
'UserTo'=>array(
'className'=>'User',
'foreignKey'=>'user_to'
)
)
...
}
This way you are defining 2 relation in each model. You can add HABTM relation too. Run bake script to build your controllers and views. Then in your code you can use something like this:
$this->User->UserFrom->find('all',
array(
'conditions'=>array('user_from'=>1),
'contain'=>array('UserTo')
)
);
This should return friends of user with ID 1 and all friends details.
Be careful with the recursive queries. :)

How do I link one table two times to another table using cakePHP

I'm trying to set up a social networking type of site, where users can have friends and send each other messages.
I have a users table, and a friends table, which basically has an user_id and user_friends_id.
Using cakePHP, how can I link the user_id and user_friend_id back to the users table?
I used bake to create all my models and controllers, but when I viewed the users page, I got an error because cakePHP doesn't know how to link the user_friend_id back to the users table.
Can anyone please help?
table names (fields):
users (user_id, user fields....)
friends_users (user_id, friend_id)
associations:
User hasAndBelongsToMany Friend
Friend hasAndBelongsToMany User
in User model:
var $hasAndBelongsToMany = array(
'Friend' => array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
);
in Friend model:
var $useTable = 'users';
var $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'user_id',
);

Resources