I select Blog entries by changing hasAndBelongsToMany conditions on the fly, it doesnt work anymore for me with cakephp 1.3.
Strange problem cause it was working fine with 1.2, in the model i test it by putting a condition with a static id to see what happen, (Tag.name => 'libros'). but it pass though the hasAndBelongsToMany condition. Bring me whatever results.
var $hasAndBelongsToMany = array('Tag' =>
array('className' => 'Tag',
'joinTable' => 'blogs_tags',
'foreignKey' => 'blog_id',
'associationForeignKey'=> 'tag_id',
'conditions' => '',
'order' => '',
'limit' => '',
'unique' => true,
'finderSql' => '',
'deleteQuery'=> ''
)
in the controller
$this->Blog->bindModel(array(
'hasAndBelongsToMany' => array(
'Tag' => array('conditions'=>array('Tag.name'=>'libros'))
)));
$this->Blog->find('all');
Now i dont have mysql error anymore , but i have others records with others results. Weird.
If you have a correct database structure, must use this=
$this->Blog->bindModel(array(
'hasOne' => array(
'BlogsTag',
'FilterTag' => array(
'className' => 'Tag',
'foreignKey' => false,
'conditions' => array('FilterTag.id = BlogsTag.tag_id')
))));
$data = $this->Blog->find('all', array(
'fields' => array('Blog.*'),
'conditions'=>array('FilterTag.name'=>'libros')
));
you can read more about this at :
http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM
Related
I have a pretty typical Comment model where Comment belongsto many other models such as Article, Review, Photo, etc and in turn each of those models hasmany Comment. Here is how I built the relationship on the Comment model...
<?php
App::uses('AppModel', 'Model');
class Comment extends AppModel {
var $name = "Comment";
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Article' => array(
'className' => 'Article',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Photo' => array(
'className' => 'Photo',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Review' => array(
'className' => 'Review',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
This works like a charm wherein if I'm viewing a particular article then I can retrieve all comments from that article and it works the same for the other models. What I'm trying to do is show ALL recent comments with the original post's title no matter what model the original post is coming from (Article, Review, Photo, etc) in the format of $comment['Original']['title']. I thought adding the below code within the belongsto of the Comment model would work but it does not....
'Original' => array(
'className' => 'Article',
'foreignKey' => 'post_id',
'conditions' => array('Comment.module_id' => 3),
'fields' => '',
'order' => ''
),
'Original' => array(
'className' => 'Review',
'foreignKey' => 'post_id',
'conditions' => array('Comment.module_id' => 2),
'fields' => '',
'order' => ''
),
'Original' => array(
'className' => 'Photo',
'foreignKey' => 'post_id',
'conditions' => array('Comment.module_id' => 8),
'fields' => '',
'order' => ''
),
Unfortunately this only shows the correct title if the recent comment was on a photo (Comment.module_id = 8).
You can use CakePHP's Containable Behavior and do this:
//within a method of the Comment model
$recentComments = $this->find('all', array(
'contain' => array(
'Article',
'Photo',
'Review',
'User'
),
'limit' => 10,
'order' => $this->alias . '.created DESC'
));
Then, you'll get back the comments and any of their parents, regardless of which model it's in. After that, as you repeat through each comment, you can either do a case statement, or an if(!empty()) kinda thing to determine which model has content that you want to display.
(side note: not a good idea to create multiple associations with the same name per your attempt with "Original")
It's not surprising that you got comments only with conditions Comment.module_id = 8. You have made a basic PHP mistake. By using the same key Original multiple times you are effectively overwriting it's value each time. Choose unique aliases (array keys) for each association.
I know that i can easily find related model-data through model associations, if I select a single entry. But what I want to do is to get the first image as a thumb for the galery, when I use find('all') for the index-page.
My relations (Galleries are named Albums) are:
//Album-Model
public $hasMany = array(
'Picture' => array(
'className' => 'Picture',
'foreignKey' => 'album_id',
'dependent' => true,
'conditions' => ''
)
);
and:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Album' => array(
'className' => 'Album',
'foreignKey' => 'album_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
EDIT :
This should worked I tested it on my own!
Before your query add the following lane to specify the recursivity.
$this->Albums->recursive = 1;
$this->set('Albums', $this->Album->find('all'));
This way, it will also send the Pictures data. Then in your model associations, you can specify to only return the first image with the Album if that's what you want!
Just add 'limit' => '1', in your hasMany => Comments array, in Album Model.
Then you can iterate in your view doing
foreach($Albums as $Album){
$Album['Album']; // ALBUMS info do whatever
$Album['Picture']; // The thumbnail
}
EDIT2: I've just see you can also do
$this->Album->find('all', array('recursive' => 1));
Hi i am using Countercache in 2.0 i need to add some condition as follows.
But it is not working.. Its incrementing the field if 'counterCache' => true, It not consider the condition i added.
Post hasMany WallPost
WallPost belongs to Post
public $belongsTo = array(
'WallPost' => array(
'className' => 'WallPost',
'foreignKey' => 'wallpost_id',
'counterScope' =>array(
'WallPost.post_id' =>3,
),
'fields' => '',
'order' => '',
'counterCache' => true
),
What you want is:
public $belongsTo = array(
'WallPost' => array(
'className' => 'WallPost',
'foreignKey' => 'wallpost_id',
'fields' => '',
'order' => '',
'counterCache' => array('WallPost.post_id' =>3)
),
You are right though the documentation is confusing on this.
I'm making a Photo model, is it a good practice to make it belong to multiple models such as User, Place, etc?
Place also belongs to User
So here is my fields for Photos.
id
owner_id
type (an enum of the different models such as users and places)
Here is the belongsTo in PhotoModel that I have
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'owner_id',
'conditions' => array('Photo.type' => 'user'),
'fields' => '',
'order' => ''
),
'Place' => array(
'className' => 'place',
'foreignKey' => 'owner_id',
'conditions' => array('Photo.type' => 'place'),
'fields' => '',
'order' => ''
)
);
Or is it better to just create separate models such as UserPhoto, PlacePhoto etc?
Right now with this approach, I'm sometimes seeing dbo error when I set recursive to 2.
Thanks,
Tee
This approach can work, although if you set recursive to 2, the clearest solution is to create and/or destroy associations on the fly in such queries.
If in future you are going to use UserPhoto and PlacePhoto model, then it will be better to create separate models for them. So that you can customize those models later on. Or otherwise if you are using those models rarely then you can particularly bind those models in to your controller's method.
$this->User->bindModel(array('belongsTo' => array(
'User' => array(
'className' => 'User',
'foreignKey' => 'owner_id',
'conditions' => array('Photo.type' => 'user'),
'fields' => '',
'order' => ''
),
'Place' => array(
'className' => 'place',
'foreignKey' => 'owner_id',
'conditions' => array('Photo.type' => 'place'),
'fields' => '',
'order' => ''
)));
why cake PHP framework not recognize true syntax in this example
User has Many Photos
Photos belongs to User
In User Model
var $hasMany = array( 'Photo' => array( 'className' => 'Photo', 'foreignKey' => 'user_id' );
In Photo Model
var $belongsTo = array( 'user' => array( 'className' => 'User', 'foreignKey' => 'user_id', 'conditions' => '', 'fields' => '', 'order' => '' ), 'PhotoAlbum' => array( 'className' => 'PhotoAlbum', 'foreignKey' => 'photo_album_id', 'conditions' => '', 'fields' => '', 'order' => '', ))
in Photo controller , in add action cake generate this code :
$this->Photo->User->find('all');
but true code is :
$this->Photo->user->find('all');
means user property should upper case but cake not recognize and bake false code.
Also - the problem isn't cake. The problem is you have a var $name = "user"; in your user model.
Name your model with the cake conventions correctly and this won't happen. When you don't follow conventions you run into problems with the framework. The correct solution is to read the manual instead of posting questions with near worthless debug info here # SO.
Try setting up the $uses var. In your case in the photos_controller:
$var uses = array('User');
i find that when happen my problem , this error happen when I use association in my class and i use uppercase name for user in my code of photo model's
var $belongsTo = array( 'user' => array( 'className' => 'User', 'foreignKey' => user_id', 'conditions' => '', 'fields' => '', 'order' => '' ), 'PhotoAlbum' => array( 'className' => 'PhotoAlbum', 'foreignKey' => 'photo_album_id', 'conditions' => '', 'fields' => '', 'order' => '', ))
but user is true with Under spelling (User)
var $belongsTo = array( 'User' ...