How to use conditions in self association without joins? - mysql

I have Product model [id, parent_id, x].
I want to append on each Product, single ProductParent, only when Product.x = 0, and Product.parent_id = ProductParent.id.
What i try is:
public $hasOne = array(
'ProductParent' => array(
'className' => 'Product',
'foreignKey' => false,
'conditions' => array(
'ProductParent.id = Product.parent_id',
'Product.x' => 0
)
)
);
And get output Product.parent_id is unknown.

You can try using Tree behavior. Check this: http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html

Related

cakephp virtual fields with subquery and if

I have a Category table with a name field.
I want to be able to overwrite that name using a PartnerCategory Table and join it.
So usually I would get the Category like this:
$options = array(
'contain' => array('PartnerCategory'),
'conditions' => array(
'Category.slug' => $slug,
'Category.status' => true,
)
);
$category = $this->Category->find('first', $options);
And then check, if ParentCategory.name is not empty and replace the Category.name with it.
Overwriting the name with php is tedious so I checked virtual fields.
I can overwrite the Category.name using this:
$this->virtualFields = array(
'name' => 'SELECT name FROM app_partner_categories WHERE category_id = 1 AND partner_id = 60'
);
But if the name in the PartnerCategory table is empty or no mathes are found, the Category.name would be null.
How can I overwrite Category.name only if PartnerCategory.name is found?
Not sure but this could be a possible solution:
$joins = array(array('table' => 'app_partner_categories',
'alias' => 'PartnerCategory',
'type' => 'INNER',
'conditions' => array(
'PartnerCategory.category_id = Category.id'
)
)
);
$options = array(
'fields' => array('IF(PartnerCategory.name IS NULL or PartnerCategory.name = "", Category.name, PartnerCategory.name) as overwritten_name'),
'joins' => $joins,
'conditions' => array(
'Category.slug' => $slug,
'Category.status' => true,
)
);
$category = $this->Category->find('first', $options);

CakePHP Sort order not affecting all records

In my CakePHP 2.7.7 app, I have an issue where using PaginatorComponent isn't properly sorting my results. See this link for an image:
Sample Data
The data should be sorted by descending last name, but you can see there are a couple users who are seemingly exempt from this data. Doesn't matter what order I do it in, ascending or descending, these few records don't get sorted. For reference:
index() in UsersController:
public function index() {
$this->User->contain('Status');
$this->paginate = array(
'limit' => 15,
'order' => array('User.last_name' => 'DESC'),
'conditions' => array('User.department_id =' => $this->Session->read('Auth.User.department_id')),
'contain' => 'Status'
);
$this->set('users', $this->Paginator->paginate());
}
Any ideas what could have caused this? I'm at a loss here. Thanks in advance!
SELECT `User`.`id`, `User`.`first_name`, `User`.`last_name`, `User`.`middle`, `User`.`address`, `User`.`address_2`, `User`.`city`, `User`.`state_id`, `User`.`zip`, `User`.`home`, `User`.`cell`, `User`.`work`, `User`.`email`, `User`.`status_id`, `User`.`status_reason`, `User`.`rank`, `User`.`birthday`, `User`.`gender`, `User`.`school`, `User`.`employer`, `User`.`position`, `User`.`created`, `User`.`modified`, `User`.`updated_by`, `User`.`radio`, `User`.`ident`, `User`.`parent_name`, `User`.`parent_number`, `User`.`parent_email`, `User`.`squad`, `User`.`squad_leader`, `User`.`ride_along`, `User`.`drivers_license`, `User`.`username`, `User`.`password`, `User`.`department_id`, `User`.`join_date`, `User`.`group_id`, `User`.`test`, (CONCAT(`User`.`first_name`, " ", `User`.`last_name`)) AS `User__name`, `Status`.`id`, `Status`.`status` FROM `admin_cake`.`users` AS `User` LEFT JOIN `admin_cake`.`statuses` AS `Status` ON (`User`.`status_id` = `Status`.`id`) WHERE `User`.`department_id` = 1 ORDER BY `User`.`last_name` ASC LIMIT 15
When you use $this->paginate to set conditions, limit...you need to use function $this->pagination().
$this->pagination and $this->Paginator->pagination() can not be combined.
1)
public function index() {
$this->User->contain('Status');
$this->paginate = array(
'limit' => 15,
'order' => array('User.last_name' => 'DESC'),
'conditions' => array('User.department_id =' => $this->Session->read('Auth.User.department_id')),
'contain' => 'Status'
);
// Assign settings
$this->Paginator->settings = $this->paginate;
$this->set('users', $this->Paginator->paginate());
}
2)
public function index() {
$this->User->contain('Status');
$this->paginate = array(
'limit' => 15,
'order' => array('User.last_name' => 'DESC'),
'conditions' => array('User.department_id =' => $this->Session->read('Auth.User.department_id')),
'contain' => 'Status'
);
//Don't use $this->Paginator->paginate()
$this->set('users', $this->paginate());
}

Association of models(JOIN) not working in cakephp, shows empty results

I am purely new to cakephp and currently working on a project that is built in version 1.3. Basically I am trying to display the city names of the providers which are inserted in the database.
I have two models : gal_store.php and gal_location.php. In the gal_store model, the stores names are saved with their corresponding city ids in city field in gal_stores table. The table gal_locations contains all the cities and their names.
So I tried to JOIN the two tables as below :
var $hasOne = array(
'GalLocation' => array(
'className' => 'GalLocation',
'foreignKey' => 'id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
function getList($limit = 50,$whether_list = false){
$recursive = -1;
$conditions = array("GalStore.city"=> "GalLocation.id");
//$conditions = "";
$order = array("GalStore.address");
if($whether_list == true){
return $this->find("list",array("DISTINCT GalStore.city","recursive"=>$recursive,"limit"=>$limit,"order"=>$order,"conditions" => $conditions));
}else{
return $this->find("all",array("DISTINCT GalStore.city","recursive"=>$recursive,"limit"=>$limit,"order"=>$order,"conditions" => $conditions));
}
}
But in the ctp file when I do a var_dump($gal_locations); it always shows empty ! What is the reason ?
If the gal_locations has one to one relationship with gal_stores, use below code:
var $hasOne = array(
'GalLocation' => array(
'className' => 'GalLocation',
'foreignKey' => 'city',//if the city field contains the id of gal_locations table
'conditions' => '',
'fields' => '',
'order' => ''
),
);
If the gal_locations has one to many relationship with gal_stores, use below code:
var $belongsTo = array(
'GalLocation' => array(
'className' => 'GalLocation',
'foreignKey' => 'city',//if the city field contains the id of gal_locations table
'conditions' => '',
'fields' => '',
'order' => ''
),
);

Model association is off for joining users table on comments table for a submission

My associations in CakePHP are a bit off. Here is the problem. I have a users table
and a comments table. When retrieving a submission I want to join the users table
on the comments table with Comment.user_id == User.id.
Comment Model:
class Comment extends AppModel {
var $name = 'Comment';
var $belongsTo = array('User');
var $hasMany = array(
'CommentsLike' => array(
'className' => 'CommentsLike'
),
'Comment' => array(
'className' => 'Comment'
)
);
var $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'comments',
'foreignKey' => 'Comment.user_id',
'associationForeignKey' => 'user_id'
),
'Submission' => array(
'className' => 'Submission'
)
);
User Model:
class User extends AppModel {
var $name = 'User';
var $hasMany = array('Comment');
var $hasAndBelongsToMany = array(
'Comment' => array(
'className' => 'Comment',
'joinTable' => 'comments',
'foreignKey' => 'Comment.user_id',
'associationForeignKey' => 'user_id',
),
'Submission' => array(
'className' => 'Submission',
'order' => 'Submission.created DESC'
)
);
When I grab a submission, it grabs all comments for it, but it doesn't join on
the users table which is what I want
Submission Model:
class Submission extends AppModel {
var $name = 'Submission';
var $belongsTo = array(
'User' => array(
'className' => 'User'
)
);
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'order' => 'Comment.created DESC',
'conditions' => array(
'Comment.deleted' => 0
)
),
'SubmissionsVote' => array(
'className' => 'SubmissionsVote'
),
'SubmissionThumbnails' => array(
'className' => 'SubmissionThumbnails'
)
);
A find on a submission will return this:
[Submission] => Array
(
// removed for sake of stackoverflow length
)
[User] => Array
(
[id] => 2
[username] => bob_cobb
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[submission_id] => 112
[comment] => this is a test comment
[user_id] => 2
[created] => 5 minutes ago
[deleted] =>
[parent_id] =>
)
)
As you can see [Comment][0] should also have [Comment][0][User] or something similar.
Why would I want this? Simple: I want to grab the username of the person who
commented by the foreign key of user_id from the comments table. I've read the docs and tutorials and pretty sure I'm close on this but not sure what's holding me back.
Here is a screenshot of the comments table:
Here is a screenshot of the users table structure:
You can a couple of options:
Either set the recursive property in the Submission model to the level you need to fetch back your associated data ( see http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive )
or (more preferable) use the Containable behaviour ( see http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html ) to specify what related data to return:
class Submission extends AppModel
public $actsAs = array('Containable');
}
Use it like this in your find:
$data = $this->Submission->find('all', array(
'conditions'=>array(your conditions here),
'contain'=>array(
'User,
'Comment'=>array(
'User'
)
)
));
Most people use containable in every model so add it to AppModel and set AppModel::recursive to -1

Cakephp model with conditions

Is it possible to make relation in cakephp model with some specific conditions:
eg:
var $belongsTo = array(
'Parent' => array(
'className' => 'Category',
'foreignKey' => 'parent_id',
'dependent' => true
)
);
I want the above relation on where field parent_id is not 0. Please give some overview on How to do that?
You can put conditions in the relations just like you do with finds.
var $belongsTo = array(
'Parent' => array(
'className' => 'Category',
'foreignKey' => 'parent_id',
'dependent' => true,
'conditions' => array(
...
)
)
);