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.. :)
Related
I'm having an issue with Cake joining tables in the wrong place :(
I have three tables - CC_PLAYLIST, CC_PLAYLISTCONTENTS, and CC_FILES.
I'd like to get a list of all playlists, with all of their contents, and then the relevant file information for each piece of playlist content.
I.E
Playlist 1
-- Playlist Content 1
---- File Info
-- Playlist Content 2
---- File Info
-- Playlist Content 3
---- File Info
Playlist 2
-- Playlist Content 123
---- File Info
In my Model (AirtimePlaylist) I get this data with
$result = $this->find('all', array(
'contain' => array(
'AirtimePlaylistContent' => array(
'fields' => array('AirtimePlaylistContent.id', 'AirtimePlaylistContent.playlist_id', 'AirtimePlaylistContent.file_id'),
'AirtimeFile' => array(
'fields' => array('AirtimeFile.id', 'AirtimeFile.track_title', 'AirtimeFile.artist_name')
)
),
),
'conditions' => array('AirtimePlaylist.id' => 5),
'fields' => 'AirtimePlaylist.id', 'AirtimePlaylist.name'
));
It seems however that the join between CC_PLAYLISTCONTENTS and CC_FILES is not quite playing ball. CC_PLAYLISTCONTENTS should join CC_FILES with CC_PLAYLISTCONTENTS.file_id = CC_FILES.id but it seems to be doing CC_PLAYLISTCONTENTS.id = CC_FILES.id
AirtimePlaylist.php
class AirtimePlaylist extends AppModel {
public $useTable = 'cc_playlist';
public $actsAs = array('Containable');
public $hasMany = array('AirtimePlaylistContent' => array(
'className' => 'AirtimePlaylistContent',
'foreignKey' => 'playlist_id'
));
AirtimePlaylistContent.php
class AirtimePlaylistContent extends AppModel {
public $useTable = 'cc_playlistcontents';
public $hasOne = array('AirtimePlaylist' => array(
'className' => 'AirtimePlaylist',
'foreignKey' => 'id'
),'AirtimeFile' => array(
'className' => 'AirtimeFile',
'foreignKey' => 'id'
));
AirtimeFile.php
class AirtimeFile extends AppModel {
public $useTable = 'cc_files';
public $hasMany = array('AirtimeFileAttribute' => array(
'className' => 'AirtimeFileAttribute',
'foreignKey' => 'track_id'
));
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'
)
);
}
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',
)
);
}
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
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.