I am trying to do a find with conditions in two models. Is this possible ?
$offices = $this->User->Org->find('first', array(
'conditions' => array(
"or" => array(
'Org.website LIKE' => $match,
'Domain.domain' => $match
)
)
));
The relationship looks like this
'Domain' => array(
'className' => 'Domain',
'foreignKey' => 'org_id',
),
As a containable search
$this->User->Org->Behaviors->attach('Containable');
$offices = $this->User->Org->find('first', array(
'contain' => array(
'Domain' => array(
'conditions' => array(
'Or' => array(
'Domain.domain' => $match
)
)
),
'Office' => array(
'fields' => array('Office.id', 'Office.city')
)
),
'conditions' => array(
"or" => array(
'Org.website' => $match
)
)
));
Thanks
Alex
It's possible as long as your level of recursion is set appropriately, but I highly recommend using the Containable Behavior for something like this. It makes this things trivial, readable and surgical (you get what you need and only what you need).
Related
I am using cakephp 2.1 and defined 3 tables as follows.
`industries(id, name);`
`movies(id, name, industry_id),`
`trailers(id, name, movie_id);`
I want to paginate the trailers for particular industry. So the code I have written is below:
$this->paginate = array(
'Industry' => array(
'contain' => array(
'Movie' => array(
'order' => 'Movie.release DESC',
'Trailer' => array(
'conditions' => array(
'Trailer.id !=' => $trailer_id
)
)
)
),
'conditions' => array(
'Industry.id' => $id
)
)
);
If I would specify 'limit' for 'Trailer', I get correct number of results but some null array for a movie which doesn't contain any trailers. Please help me to get the number of specified limit of trailers for particular industry. The work will be most appreciated.
It looks to me like you've got your contain key in the wrong place. It should be defined before the models.
<?php
$this->paginate = array(
'contain' => array(
'Industry' => array(
'Movie' => array(
'order' => 'Movie.release DESC',
'Trailer' => array(
'conditions' => array(
'Trailer.id !=' => $trailer_id
)
)
)
)
),
'conditions' => array(
'Industry.id' => $id
)
);
I have four models (Location->StatisticCategory->StatisticItem->Statistic) that I'm trying to return in a single query. The results are as expected until the query starts at the level of Location. At that point the data return contains everything down to the 3rd association in StatisticItem, but every single Statistic is null. Any idea why 4th level associations (at least here) are not returning any data?
Below is the code I'm using in my StatisticsController with Containable behavior turned on in AppModel:
$stats = $this->Location->find('all', array(
'fields' => array(
'Location.id',
'Location.location'
),
'conditions' => array(),
'recursive' => 2,
'contain' => array(
'StatisticCategory' => array(
'fields' => array(
'StatisticCategory.id',
'StatisticCategory.location_id',
'StatisticCategory.category'
),
'StatisticItem' => array(
'fields' => array(
'StatisticItem.id',
'StatisticItem.statistic_category_id',
'StatisticItem.item'
),
'Statistic' => array(
'fields' => array(
'Statistic.id',
'Statistic.statistic_item_id',
'Statistic.date',
'Statistic.number'
),
'conditions' => array(
'Statistic.date' => $date
)
),
'order' => array('StatisticItem.item')
),
'order' => array('StatisticCategory.category')
)
),
'order' => array('Location.location')
));
The documentation for containable describes how to contain deeper associations. The following should be about what you're looking for:
$this->Location->find('all', array(
'contain' => array(
'StatisticCategory' => array(
'StatisticItem' => array(
'Statistic'
)
)
)
));
Is there a way in cakephp using ORM to get the item that belongs to a specific child item. For example I was to get the related Post record for a specific Comment records.
This is my Comment model:
var $belongsTo = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
I was trying this but it's pull back every post, even those that don't have the comment I'm querying against:
$this->Post->contain('Comment');
$results = $this->Post->find('all', array(
'contain' => array(
'Comment' => array(
'conditions' => array(
'id' => 15
)
)
)));
Any other way to do this?
Are you sure you don't have to specify the model in your conditions?
For example:
$this->Post->contain('Comment');
$results = $this->Post->find('all', array(
'contain' => array(
'Comment' => array(
'conditions' => array(
'Comment.id' => 15
)
)
)));
my research led me to this post regarding the issue with contains:
http://nuts-and-bolts-of-cakephp.com/2008/07/17/forcing-an-sql-join-in-cakephp/
so my final solution was as follows:
$this->Post->unbindModel(array('hasMany' => array('Comment')));
$results = $this->Post->bindModel(array('hasOne' => array(
'Comment' => array(
'foreignKey' => false,
'conditions' => array('Comment.post_id = Post.id'))
)));
$results = $this->Post->find('all', array(
'conditions' => array(
'Comment.id' => 10
)));
not pretty but gets the job done :)
I want to convert following mysql statement into cakephp query syntax.Please help me. Here is my query.SELECT * FROM post WHERE (user_id == $id OR awarded_to = $id ) AND id = $id
Here is my cakephp query. is it wrong.
$this->Post->find('all',
array('conditions' => array('OR' =>
array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'AND' =>
array('Post.id' => $id)
))
This one's on the house, but next time read the docs.
$this->Post->find('all', array(
'conditions' => array(
'OR' => array(
array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'Post.id' => $id
)
));
The 2 OR arrays need to be inside an array themself, and there's no need for AND.
Just add Post.id = $id below the OR condition without you give "and" it's automatic read as and condition...
$this->Post->find('all', array(
'conditions' => array(
'OR' => array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'Post.id' => $id
));
You are very close with your query, just you need little modification like to remove 'AND' in conditions array after 'OR' as:
$this->Post->find('all', array(
'conditions' => array(
'OR' => array(
array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'Post.id' => $id
)
));
Or
$this->Post->find('all', array(
'conditions' => array(
'Post.id' => $id
)
));
The second option will be the best for you if you are passing tables primary key 'id' in AND conditions.
I am trying to select only distinct related model entries but it seems it doesn't work.
I have this:
$active_questions = $this->Question->find('all', array('conditions' => array('test_id' => $active_tests), 'fields' => array('answer_style_id'), 'contain' => array(
'Answer' => array(
'fields' => array('capital_category_id'),
'CapitalCategory' => array(
'fields' => array('id', 'DISTINCT capital_id', 'DISTINCT category_id', 'delete_flag'),
'Capital' => array(
'fields' => array('id', 'delete_flag')
),
'Category' => array(
'fields' => array('id', 'delete_flag')
)
)
)
)));
But Cake seems to automatically add the associated model key, even id I specified it with a DISTINCT keyword:
Query: SELECT `CapitalCategory`.`id`, DISTINCT `CapitalCategory`.`capital_id`, DISTINCT `CapitalCategory`.`category_id`, `CapitalCategory`.`delete_flag`, `CapitalCategory`.`capital_id`, `CapitalCategory`.`category_id` FROM `capital_categories` AS `CapitalCategory` WHERE `CapitalCategory`.`id` = 217
How do I filter out only DISTINCT capitals or categories? For the current example, Cake returns 20 categories with the same id. I want only one to be returned.
Thank you.
Off the top of my head, the following may work using the 'group' option
$active_questions = $this->Question->find(
'all',
array(
'conditions' => array('Question.test_id' => $active_tests),
'fields' => array('answer_style_id'),
'contain' => array(
'Answer' => array(
'fields' => array('capital_category_id'),
'CapitalCategory' => array(
'fields' => array('id', 'capital_id', 'category_id', 'delete_flag'),
'group' => array('capital_id', 'category_id'),
'Capital' => array(
'fields' => array('id', 'delete_flag')
),
'Category' => array(
'fields' => array('id', 'delete_flag')
)
)
)
)
)
);
Why don't you put 'group' just below 'fields' and not inside 'contain', also you may have to remove 'fields' altogether.