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);
Related
In a Silverstripe (version 3) model admin, how can I get the collection of fields from a different model so as to add them to this model's admin?
I have tried this using FieldList::addFieldsToTab:
$loremIpsumTab = Tab::create('LoremIpsum');
$fields->fieldByName('Root')->insertAfter('Main', $loremIpsumTab);
$loremIpsumFields = (
$this->LoremIpsum()->getCMSFields()
->fieldByName('Root.Main')->Fields());
$fields->addFieldsToTab('Root.LoremIpsum', $loremIpsumFields);
That creates the tab correctly, but moves the fields incorrectly: all the fields from 'Root.Main' are moved, not only those for the LoremIpsum model.
I had assumed this would interrogate the related LoremIpsum model for its CMS fields:
$this->LoremIpsum()->getCMSFields()
->fieldByName('Root.Main')->Fields()
So how can I move only those fields for the LoremIpsum model?
Hello and welcome to StackOverflow. What do you want to acchieve?
It seems you want to edit a has_one relation dataobject from your other dataobject. There are ready-to-use and tested modules for this scenario, e.g. https://github.com/stevie-mayhew/hasoneedit/tree/3.x , cause even if you manage to display the fields, SilverStripe assumes those values belong to the current model and not to a relation. Then you'll have extra work to save it back etc...
Some fields in your current model and in the LoremIpsum model have the same name, e.g. ID, Title, Created. This causes problems in your code above, cause you can only have one Field for e.g. ID in a Form.
The "hasoneedit" module overcomes this by prefixing the relation's fields.
Say I have models User and Post
Clearly, User hasMany Post
But now I want to have subscriptions.
Do I create a second relationship user/post relationship that is HABTM in addition to the relationship they already have?
I think that you need to create the relation User belongsTo Subscriptions.
I do not see that having a relationship HABTM
You could do this with two different hasMany associations, a new belongsTo association, or a new HABTM association. It really depends on how you want to organize and access your data.
To answer the question you posed in the comments, yes, it's possible to have multiple relationships between the same set of Models. Please read: Multiple relations to the same model from the Cake book.
Of course you can add more than one relation on the same model. You han have: User hasMany Post
User hasMany Subscription
Post belongsTo User
Subscription belongsTo User
On both direction you can get all users's posts and posts that belong to users.
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.
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
I'm quite new to CakePHP so I'm wondering if anyone can help me with how to order my pages.
I have a table of products (with a Product model and products_controller).
I also have a table of categories (with a Category model and categories_controller).
The categories hasMany products.
Firstly, is the name categories incorrect to call it. According to CakePHP convention, what is the correct name to call it?
Secondly I would like the user to click on the products link and then be presented with a list of categories and finally, once he/she chooses a category be presented with the products in that category. How would this be laid out?
You're asking some pretty basic CakePHP stuff, I suggest you read the book, which outlines naming conventions, file structure and data retrieval to name a few things.
That being said, the name categories is correct, unless you want products to have more than one category, the relationship will be Product 'BelongsTo' Category.
To get category info inside the product controller you can just access it's find methods with $this->Product->Category->find();, but again I recommend you read through the CakePHP book as you go to build up our knowledge and learn more about the framework you're using.
You mean that categories is not a plural of category? I think so. Your table has to be named as 'categories'.
Secondly, I think that you need a Categories hasAndBelongsToMany Products (HABTM) in your model, so every Category has many Products, and also a Category belongs to many products.
Use the 'cake bake' command and you will see easily if it is what you want.
Hope it helped, althought I'm quite new in cakePHP as well...
Alf.
If you have categories tables in db, its controller would be categories_controller.php and the Products belongsTo Category will work if products belong to only one category. No need to HABTM relationship. See in cakephp the model files are in singular form and controller file are in plural form with controller attached with them. The tables are named in plural in db.
Regarding ur 2nd question, I think im not getting it exactly.