I'm using the cakephp framework to develop an application and I'm running into some trouble understanding the associations between these models fully. Below you can see the four models along with their relative database fields.
User
id
Profile
id
user_id
Post (A blog post on the users profile)
id
profile_id
topic_id
Topic (A topic for a blog post)
id
name
Here are the associations as they currently stand:
User
hasOne: Profile
Profile
hasMany: Posts
Post
belongsTo: Topic, Profile
Now my problem. I am unsure if you have to define associations like User hasMany Posts or if it's already assumed because User hasOne Profile and Profile hasMany Posts. My other problem is defining the relationship between a post and its topic.
A profile can have unlimited posts
A post must be associated with a profile
A post can only have one topic
The topic table contains a list of all topics
A post does not NEED a topic
Given these criteria how should my associations look? All the research I've done on associations only shows simple examples.
I'm using CakePHP version 2.1.3
Thanks for any and all help and/or advice in advance
You can recursively find associations of associations, or even better, use Containable.
In the model (I recommend putting it in AppModel, since I find myself using Containable for everything):
class AppModel extends Model {
public $actsAs = array('Containable');
...
}
Then when you call read (or find, or paginate) for User, most likely in your controller, do this:
$this->User->contain(array(
'Profile' => array(
'Post'
)
));
$data = $this->User->read();
$set('user',$data);
If you set that data to your view, you can then access the id of one of the posts from $user['Profile']['Post'][0]['id'].
Now for your next question, you can have conditional associations.
public $hasMany = array(
'Topic' => array(
'className' => 'Topic',
'conditions' => 'Post.topic_id IS NOT NULL'
)
)
I think everything looks fine
Your assumption is correct you dont have to define the User / Post relationship. Users dont have many Posts, Profiles do. You could store the user_id on the Post rather than profile_id to make thing a bit more intuitive but thats up to you.
Topic hasMany Post and you are done. The topic/post conditions you describe can be controlled via the forms and before saves on the model. For example 'A post must be associated with a profile', well at the point you save the post you add in the profile_id based on session info of the logged in user.
Related
I'm sorry. I thought about it but I can't come to a better title since I don't know how to describe this problem in one sentence.
Anyway, I am building a news feed just as Facebook where users can post a wall message and other users can comment on it.
I have 3 Tables in the database
profiles Table which contains the file name for their profile picture. posts table which contains details about posts and comments table for comments.
I have the below code in my Post model
public $belongsTo = 'Profile';
public $hasMany = 'Comment';
by doing that I can get the comments associated with each posts. But I am not able to get the profile picture from profiles table for "commenter". I tried
public $belongsTo = 'Profile;
in the Comment model too but it's not working.
How would I go about searching for a model across a related model? I have an author model and a post model. The author model has a "HAS_MANY" relation with posts and the post has a "BELONGS_TO" relation to an author. Essentially, each author has many posts. Given an author name and a post name, I need to get the post that fulfills this criteria. There will only be one match as the combination of author name and post name are unique. (this, I have working) The "author name" resides with the author model and the "post name" resides with the post model.
For non-relational models, I've been using this to find models:
ExampleModel::model()->findByAttributes(array('name' => $nameInput));
but I can't seem to figure out how to search across relations like I described above.
Use a CDbCriteria instance and CActiveRecord::find() instead i.e
$c=new CDbCriteria
$c->together=true;
$c->with=array('author'); //the name of the related model in the model you are searching
// the format for searching related fields is relation.field
$c->compare('author.name',$nameInput);
$c->compare('name',$postInput);
$post=Post::model()->find($c);
I have two models in a CakePHP application: Users and Groups. Initially I had not relationships between the two. Now in the database table groups, I manually add the column user_id so that now I have the following relationships between the two:
Groups belongsTo Users
Users hasMany Groups
Now after doing this for some reason I keep getting the following error:
1054: Unknown column 'Group.user_id' in 'field list'
I tried to run CakePHP's bake command to see if Cake will automatically detect the relationship between my two models. When I try to bake the User model, CakePHP does not even detect that there is a hasMany relationship between User and Group. Any idea why is this happenning and how I can fix this please?
Thank you
Perhaps I am misunderstanding how you want your associations, but I would imagine that:
A User belongsTo a Group
A Group hasMany Users
Example User model:
class User extends AppModel {
public $belongsTo = array(
'Group' => array(
'className' => 'Group',
'foreignKey' => 'group_id'
)
);
}
Example Group model:
class Group extends AppModel {
public $hasMany = 'User';
}
Your Users table will need a group_id field.
All of this is assuming that you want one group per user. If you want Users to have multiple groups then you may wish to define a HABTM relationship between Users and Groups, or perhaps researching Access Control Lists may point you in a better direction (I have yet to utilize Cake's ACL component yet).
Either way, I highly suggest reviewing the Cakebook page on Associations: Linking Models Together.
I've got an uploads controller which handles video file formats. In the uploads controller you are able to browse all the videos uploaded and watch them. In the function watch I have a comments element which updates the comments table with the userid (comment left by user that is currently logged in) uploadid (uploaded that is currently being watched) and the comment (comment of the user).
I've got the form working perfectly, however I'm not to sure how I would acquire the information from the comments table, such as the necessary query to be implemented?
Any suggestions?
I saw your other post CakePHP Elements not updating table, so I sort of have an idea of your situation. It seems you are representing comments with your Post model.
You want to query data from your Post model, in your UploadsController, correct?
If your comments table is named comments, you need to ensure it is associated to your Post model. Cake automatically associates Models and database tables if they follow Cake's naming conventions. But if they are in fact different, you can specify a custom database table for your Post model:
<?php
class Post extends AppModel {
var $useTable = "comments" /*Or whatever you named your comments table*/
...
}
?>
You also have to ensure the model associations are set up between Post and Upload:
Post belongsTo Upload
Upload hasMany Post
I noticed you have:
Post belongsTo Upload
Upload hasAndBelongsToMany Post
Is there a reason why it is HABTM? HABTM implies that the same Post can belong to many different Uploads. hasMany implies that a Post can only belong to a single Upload.
Finally, now that the model associations are set up, you can access related models in a controller:
<?php
class UploadsController extends AppController {
...
function watch ($id = null) {
$this->Upload->id = $id;
$this->set('uploads', $this->Upload->read());
/* To get related comments (Posts) */
$related_comments = $this->Upload->Post->find('all', array(
'conditions' => array(
'Upload.id' => $id /* This condition makes it so only associated comments are found */
)
));
$this->set('comments', $related_comments);
}
...
}
?>
quick question that I have been stuck with since hours:
For my cakePHP website project (using version 2.0) I have 2 Models. They are a bit obscure so I'll translate the model to the standard blog post models.
So I have a "Posts" model and for those many "Categories".
class Post
$belongsTo = 'Category'
class Category
$hasMany = 'Post'
So far so good. Now I want every category to have exactly one (mandatory) 'main post'.
How would I associate that?
Another 'MainPost' Model? That seems redundant as it would have the same content as the posts.
A boolean 'is_main' column in the posts? Doesn't seem right since only one post of each category is allowed to be "main".
A 'mainpost_id' column in the categories? Sounds good but "$belongsTo" is the only association that allows the foreign key to be in the current class. And to say that a Category belongsTo Post when the opposite is also true seems wrong to me. Also belongsTo is a many-to-one association and what I want is kind of a one-to-one association.
Please help me, [insert name]. You're my only hope. ;)
Edit: I guess it would be great if there was a way to have a "hasOne" relationship but have the foreign key in the same class that $hasOne X and not in the other as is standard.
Here is one solution:
[ categories ]
id
name
mainpost_id
[ posts ]
id
category_id
title
text
Category hasMany Post
Post belongsTo Category
Category hasOne MainPost (see code)
i think you use hasAndBelongsToMany relationship....see more details at this link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html