CakePHP - Related models in a relationship table, displaying in a drop down? - php

Given the following table structures:
Registered Participant model:
<?php
class RegisteredParticipant extends AppModel {
var $name = "RegisteredParticipant";
var $primaryKey = "id";
var $belongsTo = array(
'EventLocation' => array('className' => 'EventLocation'),
'RegistrationStatus' => array('className' => 'RegistrationStatus'),
'Specialty' => array('className' => 'Specialty')
);
var $hasMany = array(
'DietaryRestriction' => array('className' => 'DietaryRestriction')
);
}
?>
Event Location model:
<?php
class EventLocation extends AppModel {
var $name = 'EventLocation';
var $primaryKey = 'id';
var $belongsTo = array(
'Event' => array('className' => 'Event', 'foreignKey' => 'event_id'),
'Location' => array('className' => 'Location', 'foreignKey' => 'location_id')
);
}
?>
When I do this in my view:
echo $form->input('RegisteredParticipant.EventLocation.moderator');
It returns a dropdown list of the EventLocation.ids, not the EventLocation.moderators like I expected. Any ideas what it could be?

nobody mentioned adding the $displayField to the model like this.
class EventLocation extends AppModel {
var $name = 'EventLocation';
var $displayField = 'moderators';
var $primaryKey = 'id';
var $belongsTo = array(
'Event' => array('className' => 'Event', 'foreignKey' => 'event_id'),
'Location' => array('className' => 'Location', 'foreignKey' => 'location_id')
);
}

Duh. $this->RegisteredParticipant->EventLocation->find() wasn't using 'all' as it's param.

You can use find('list') for dropdowns. E.g:
$locations = $this->RegisteredParticipant->EventLocation->find('list', array(
'fields' => array('some_fields')
));
$this->set('locations', $locations);
You will get back an array like:
array(
'id_1' => 'some_field_contents',
'id_2' => 'some_field_contents',
'id_3' => 'some_field_contents'
);
Which can be handled on your view automatically by the Form helper.

Related

Sort in cakephp other model

I have multiple tables associated with each other:
Messages
Message details
Message details has the fields id, Message_id, created_date and message.
I want to sort messages on the message details created_date.
How can I do that?
$messages = $this->Message->find('all', array(
'conditions' => array('Message.status'=> 'progress')
));
// What do I do now to sort it on message_details created time?
class MessageDetail extends AppModel {
//public $hasMany=array('MessageDetail');
//$belongsTo = array('Message');
public $belongsTo = array(
'Message' => array(
'className' => 'Message',
'foreignKey' => 'message_id'
)
);
}
class Message extends AppModel {
public $hasMany=array('MessageDetail');
}
Can You pls try this code,You need Descending order put DESC instead of ASC
$messages = $this->Message->find('all', array(
'conditions' => array('Message.status'=> 'progress'),
'order' => array('MessageDetails.created_date ASC')
));
You can simple pass order, and mention which field to sort, see below:
$messages = $this->Message->find('all', array(
'conditions' => array('Message.status'=> 'progress'),
'ORDER' => 'MessageDetail.created_date ASC'
));
UPDATE
You Message.php Model will look like:
class Message extends AppModel {
public $hasMany = array(
'MessageDetail' => array(
'className' => 'MessageDetail',
'foreignKey' => 'message_id',
'order' => 'MessageDetail.created_date DESC'
),
);
}
and MessageDetail.php Model will be:
class MessageDetail extends AppModel {
public $belongsTo = array(
'Message' => array(
'className' => 'Message',
'foreignKey' => 'message_id'
)
);
}

Cakephp 2.x multiple relationship

i have some troubles with cakephp 2.x and the relationship of the models, i have 3 models, Post, User and Comment.
I would like bind the Post with his User and Comment with his User.
In Post Model:
$belongsTo = array('Comment','User'),
$hasMany = array('CommentOfPost'=>array('className'=>'Comment'));
I have Post bind with User, and all comment from the post but i don't have users of the comments.
Edit :
Sql output
1 SELECT `Post`.`id`, `Post`.`title`, `Post`.`content`, `Post`.`tags`, `Post`.`created`, `Post`.`modified`, `Post`.`user_id`, `User`.`id`, `User`.`username`, `User`.`password`, `User`.`role`, `User`.`name`, `User`.`lastname`, `User`.`birthdate`, `User`.`email`, `User`.`created`, `User`.`modified` FROM `blog`.`posts` AS `Post` LEFT JOIN `blog`.`users` AS `User` ON (`Post`.`user_id` = `User`.`id`) WHERE `Post`.`id` = 16 LIMIT 1 1 1 0
2 SELECT `CommentOfPost`.`id`, `CommentOfPost`.`post_id`, `CommentOfPost`.`user_id`, `CommentOfPost`.`content`, `CommentOfPost`.`created` FROM `blog`.`comments` AS `CommentOfPost` WHERE `CommentOfPost`.`post_id` = (16)
Edit :
Comment Model
public $belongsTo = array('User' => array('className' => 'User'));
Post Model
public $belongsTo = array('Comment' => array('className' => 'Comment'));
Edit :
Thank for reply, i have the same result like before i have Post and his User and Post and his comments but not users of comments
Now my model Post
$hasMany = array(
'Comment' => array(
'className' => 'Comment',
)
),
$belongsTo = array(
'User' => array(
'className' => 'User',
)
);
User model
$hasMany = array('Comment' => array('className' => 'Comment'));
Comment Model
$belongsTo = array('Users' => array('className' => 'User'), 'Posts' => array('clasName' => 'Post'));
I use paginate querying in my PostsController
$this->Paginator->settings = $this->paginate;
$data = $this->Paginator->paginate('Post');
$this->set('posts', $data);
Edit :
My paginate params
$paginate = array(
'limit' => 10,
'recursive' => 2,
'order' => array(
'Post.id' => 'desc'
)
);
I try with and without recursive option
Ok it's done !
For resume i have :
class User extends AppModel {
public $hasMany = array('Comment' => array('className' => 'Comment'));
}
class Post extends AppModel
{
$hasMany = array(
'Comment' => array(
'className' => 'Comment',
)
),
$belongsTo = array(
'User' => array(
'className' => 'User',
)
);
}
class Comment extends AppModel {
public $belongsTo = array('User' => array('className' => 'User'), 'Post' => array('clasName' => 'Post'));
}
PostsController extends AppController
{
....
$this->Post->recursive = 2;
$post = $this->Post->findById($id);
...
}
Thank for your help guys, you're awesome !
Post does not belongs to Comment. It has many comments.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Example from the cookbook:
class User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
}
For your application:
class Post extends AppModel {
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
)
);
public $belongsTo = array(
'User' => array(
'className' => 'User',
)
);
}

Not getting all the data I need for an association in CakePHP app

I have built an app in CakePHP where Users can be friends with other Users. A user has a profile and the friendships are linked between then user ids in a friends table (models further down)
In my FriendsController I pass a username and then use the following method to get Friends for a User: Note this method is in my User Model and called like: $this->User->getFriends($username); in my FriendsController!
function getFriends($username) {
//Start by getting User's ID
$user = $this->find(
'first',
array(
'conditions' => array(
'User.username' => $username
)
)
);
$profileAndFriends = $this->Profile->find(
'first', //Because User hasOne Profile, so we'll fetch this one profile.
array(
'conditions' => array(
'Profile.user_id' => $user['User']['id']
),
'contain' => array(
'UserFrom' => array(
'conditions' => array(
'status' => 1
)
),
'UserTo' => array(
'conditions' => array(
'status' => 1
)
)
)
)
);
return $profileAndFriends;
}
My User Model:
class User extends AppModel
{
public $name = 'User';
public $hasOne = 'Profile';
public $hasMany = array(
'UserFrom'=>array(
'className'=>'Friend',
'foreignKey'=>'user_from'
),
'UserTo'=>array(
'className'=>'Friend',
'foreignKey'=>'user_to'
)
);
}
and my Profile model:
class Profile extends AppModel
{
public $name = 'Profile';
public $belongsTo = 'User';
}
and the Friend model:
class Friend extends AppModel
{
var $name = 'Friend';
public $belongsTo = array(
'UserFrom'=>array(
'className'=>'User',
'foreignKey'=>'user_from'
),
'UserTo'=>array(
'className'=>'User',
'foreignKey'=>'user_to'
)
);
}
So in my view I have:
<?php foreach ($friends as $friend) : ?>
<?php echo $friend['UserTo']['firstname']; ?>
<?php endforeach; ?>
However it can't understand the firstname part! So...
If I do a debug on $friend in the view I get:
array(
'Friend' => array(
'id' => '1',
'user_from' => '6',
'user_to' => '8',
'created' => '0000-00-00 00:00:00',
'status' => '1'
),
'UserFrom' => array(
'password' => '*****',
'id' => '6',
'username' => 'driz',
'email' => 'cameron#driz.co.uk',
'status' => '1',
'code' => '6d446abefc2f1214e561da6f93470621',
'lastlogin' => '2012-04-23 15:22:04',
'created' => '0000-00-00 00:00:00'
),
'UserTo' => array(
'password' => '*****',
'id' => '8',
'username' => 'testperson',
'email' => 'test#testperson.com',
'status' => '1',
'code' => '7a794859b3a16dfc005dd7f80b9ac030',
'lastlogin' => '2012-03-18 09:28:24',
'created' => '0000-00-00 00:00:00'
)
)
So it's clearly an issue of the Linked Users I need to also contain there profiles... But how do I do that as If I put a contain inside the UserTo and UserFrom it throws an error saying they're not associated...
class User extends AppModel {
public $name = 'User';
public $hasOne = 'Profile';
public $belongsTo = array(
'Friend'=>array(
'foreignKey' => 'user_to'
)
);
}
class Profile extends AppModel {
public $name = 'Profile';
public $belongsTo = 'User';
}
class Friend extends AppModel {
public $name = 'Friend';
public $hasOne = 'User';
}
Now its possible to take user friends by:
$this->Friend->find("all", array(
'conditions'=>array(
'Friend.user_from'=>$user_id,
)
'contain'=>array(
'User'=>array(
'contain'=>'Profile'
)
)
));

CakePHP - Associations Problems

I'm trying to make it so when I do a $this->Topic->find('all'), it will pull all the associated User data, and all the associated Post data. The problem is that I can't manage to do that right now.
Right now I do $this->User->find('all'), which returns the Topic data, and all Posts inside that Topic. I guess this is what my code tells it to do, but it's not what I want. Please forgive my explanation.. I really suck at CakePHP associations.
Here are my models for your reference:
Topic.php
class Topic extends AppModel {
var $name = 'Topic';
var $actsAs = array('Containable');
var $hasMany = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'topicid'
)
);
var $hasOne = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'id'
)
);
var $belongsTo = array(
'Forum' => array(
'className' => 'Forum',
'foreignKey' => 'id'
)
);
}
Post.php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array('Containable');
var $hasOne = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'id'
)
);
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'userid'
),
'Topic' => array(
'className' => 'Topic',
'foreignKey' => 'topicid'
)
);
}
Forum.php
class Forum extends AppModel {
var $name = 'Forum';
var $hasMany = array(
'Topic' => array(
'className' => 'Topic',
'foreignKey' => 'forumid'
)
);
}
User.php
class User extends AppModel {
var $name = 'User';
var $actsAs = array('Containable');
var $hasMany = array(
'ForumPost' => array(
'className' => 'ForumPost',
'foreignKey' => 'userid'
),
'ForumTopic' => array(
'className' => 'ForumTopic',
'foreignKey' => 'userid'
)
);
}
I want it so that I can do $this->Topic->find('all'), and it gives me the Topic data, then the Post data for each Post in the Topic, and the User data for each Post in the Topic (respectively)..
Thanks for any help.
I found out my problem, thanks to savant in the #cakephp IRC channel. My models were named wrong.. :)

Cakephp: multiple levels of belongsto in model

In a model, is it possible to do multiple iterations of belongsTo?
Assuming 3 tables, alerts, schedules, tasks and the model is for alerts. I want to get at a field from tasks but I have to join through schedules.
alerts.schedule_id -> schedules.tasks_id -> tasks.name
I tried this syntax:
var $belongsTo = array(
'Schedule' => array(
'className' => 'Schedule',
'foreignKey' => 'schedule_id'
),
'Task' => array(
'className' => 'Task',
'foreignKey' => 'task_id'
));
But that just joins both Schedules and Tasks directly to Alerts (here's the sql that was generated:
LEFT JOIN `schedules` AS `Schedule` ON (`Alert`.`schedule_id` = `Schedule`.`id`) LEFT JOIN `tasks` AS `Task` ON (`Alert`.`task_id` = `Task`.`id`)
)
I ended up setting this property:
$this->Alert->recursive = 2;
In the index() function of the alerts controller.
Then I didn't have to do a separate find and was able to reference the name field in the Tasks table in index.ctp like this:
<td><?php echo $alert['Schedule']['Task']['name']; ?> </td>
Try this.
in alert.php
CLass Alert extends AppModel{
var $name = 'Alert';
var $belongsTo = array(
'Schedule' => array(
'className' => 'Schedule',
'foreignKey' => 'schedule_id'
)
);
}
in schedule.php
CLass Schedule extends AppModel{
var $name = 'Schedule';
var $belongsTo = array(
'Task' => array(
'className' => 'Task',
'foreignKey' => 'task_id'
)
);
}
then find with recursive=>2

Categories