Cakephp run time bindmodel associaton group by is not working - php

with the updated code i am trying to bind relation between payment and website , but it seems group by is not working. and i am getting lot of duplicate result.
Updated :
$this->Website->unBindModel(array('hasMany' => array('User')));
$this->Website->bindModel(array(
'hasMany' => array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'website_id',
'fields' => array(
'Payment.id',
'Payment.website_id',
'Payment.created',
'Payment.user_id',
'Payment.is_get_invoice'
) ,
'conditions' => array(
'Payment.website_id <>' => '0',
'Payment.is_get_invoice' => '0'
),
'order' => array(
'Payment.id DESC'
),
'group' => array(
'Payment.website_id' //Its not working
)
)
)
)
);
$this->Website->recursive = 1;
$webPayments = $this->Website->find('all', array('fields' => array('Website.id'),'contain' => array('Payment')));
Old :
I am trying to bind and unbind model runtime.
but its giving me error. even association is not working.
$this->Website->unBindModel(array(
'hasMany' => array(
'User'
)
));
$this->Website->bindModel(array(
'hasMany' => array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'website_id'
)
)
));
$this->Website->recursive = 1;
$webPayments = $this->Website->find('all', array(
'fields' => array(
'Website.id',
'Payment.id',
'Payment.website_id',
'Payment.created',
'Payment.user_id'
) ,
'conditions' => array(
'Payment.website_id <>' => '0',
'Payment.is_get_invoice' => '0'
) ,
'order' => array(
'Payment.id DESC',
'group' => array(
'Payment.website_id'
)
)
));
pr($webPayments);
Error:
Columnnotfound: 1054 Unknowncolumn 'Payment.id' in 'field list'
SELECT`Website` . `id`, `Payment` . `id`, `Payment` . `website_id`, `Payment` . `created`, `Payment` . `user_id`, FROM`websites` AS `Website`WHERE`Payment` . `website_id` <> 0 AND `Payment` . `is_get_invoice` = '0' AND `Payment` . `created` > '2017-04-13 07:07:54' GROUPBY `Payment` . `website_id` ORDERBY `Payment` . `id` DESC

Try using contain like this:
$webPayments = $this->Website->find('all', array(
'fields' => array(
'Website.id',
),
'contain' => array(
'Payment' => array(
'fields' => array(
'Payment.id',
'Payment.website_id',
'Payment.created',
'Payment.user_id'
),
'conditions' => array(
'Payment.website_id <>' => '0',
'Payment.is_get_invoice' => '0'
),
'order' => array(
'Payment.id DESC',
'group' => array(
'Payment.website_id'
)
)
)
)
));
https://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html

Are your models declared properly for the association? You should have
class Payment extends AppModel {
var $name = 'Payment';
public $actAs = array('Containable');
public $belongsTo = array (
'Website' => array(
'className' => 'Website',
'foreignKey' => 'website_id'
)
)
[...]
}
class Website extends AppModel {
var $name 'Website';
public $actAs = array('Containable');
public $hasMany = array(
'Payment' => array(
'className'=>'Payment',
'order' => 'Payment.id DESC'
)
)
[...]
}
I find that declaring things as low as possible in the model really works better than trying to do it on the fly with a query.. If the association is properly declared in the model itself you shouldn't have to dork with binding/unbinding like that..

The hasMany association does not support the group by key.
In this particular case, what you are trying to achieve by the incorrect use of group is to return just one result. Note that the same functionality can be accomplished by using the limit key, which is supported.
The code would be the following:
$this->Website->unBindModel(array('hasMany' => array('User')));
$this->Website->bindModel(array(
'hasMany' => array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'website_id',
'fields' => array(
'Payment.id',
'Payment.website_id',
'Payment.created',
'Payment.user_id',
'Payment.is_get_invoice'
) ,
'conditions' => array(
'Payment.website_id <>' => '0',
'Payment.is_get_invoice' => '0'
),
'order' => array(
'Payment.id DESC'
),
'limit' => 1
)
)
)
)
);
Reference
CakePHP 2.x hasMany Association

Related

Cakephp 2.8.x Query access violation when i try the CakePHP way. Normal query works

I created a query, but now i need to refactor it to the CakePHP standard. Only i can't seem to get it working.
This is my working query:
$query = $this->Transfer->query( "SELECT DISTINCT emailaddresses.emailaddress
FROM transfers
JOIN emailaddresses
ON (emailaddresses.transfer_id = transfers.transfer_id AND emailaddresses.type <> 'SENDER' AND emailaddresses.received_state = 'DELIVERED')
WHERE transfers.created_user_id = $created_user_id " );
This query is working, but when i try to Cakeify it i get access denied for table emailaddress. This is the CakePHP query:
$query = $this->Transfer->find('all', array(
'fields' => 'DISTINCT Emailaddress.emailaddress ',
'conditions' => array(
'transfers.created_user_id' => $created_user_id
),
'joins' => array(
array(
'table' => 'Emailaddress.emailaddress',
'type' => 'INNER',
'conditions' => array(
'Emailaddress.transfer_id' => 'Transfer.transfer_id',
'Emailaddress.type' => 'SENDER',
'Emailaddress.received_state' => 'DELIVERED'
)
)
)
));
What do i need to change to get this query working with the Cake standards?
Your query would be like:
$query = $this->Transfer->find('all', array(
//'fields' => 'DISTINCT Emailaddress.emailaddress ',
'fields' => array('DISTINCT Emailaddress.emailaddress '),
'conditions' => array(
//'transfers.created_user_id' => $created_user_id
'Transfer.created_user_id' => $created_user_id
),
'joins' => array(
array(
//'table' => 'Emailaddress.emailaddress',
'table' => 'emailaddresses',
'alias' => 'Emailaddress', // add alias
'type' => 'INNER',
'conditions' => array(
'Emailaddress.transfer_id' => 'Transfer.transfer_id',
//'Emailaddress.type' => 'SENDER',
'Emailaddress.type <>' => 'SENDER',
'Emailaddress.received_state' => 'DELIVERED'
)
)
)
));
Read more:
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#find
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables

HABTM Cake php find

I have tables below with HABTM associations.
user, group , groups_users
group , project, projects_groups
public $hasAndBelongsToMany = array(
'Group' =>
array(
'className' => 'Group',
'joinTable' => 'groups_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'group_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => ''
)
);
I am trying to get all users, as a list for checkboxes, that are on a project using project id using query below
$users = $this->User->Group->Project->find('list',
array(
'conditions' => array('Project.id' => $this->Session->read('Projectid'))
,'contain' => array(
'User' => array( 'fields' => 'User.id', 'User.email')
)
)
);
But error below
Model "Project" is not associated with model "User"
I have actually tried different ways to get this working but cant seem to get it right, how can i achieve what i want. cheers
I achieved what i wanted with joins , is there a way to do this by using model associations, instead of the manual joins option?
$options['joins'] = array(
array('table' => 'groups_users',
'alias' => 'gu',
'type' => 'LEFT',
'conditions' => array(
'gu.user_id = User.id',
)
),
array('table' => 'projectGroups',
'alias' => 'pg',
'type' => 'LEFT',
'conditions' => array(
'pg.group_id = gu.group_id',
)
)
);
$this->User->recursive = -1;
$options['conditions'] = array(
'pg.project_id = ' => $this->Session->read('Projectid'),
'User.Active = ' => true
);
$users = $this->User->find('list', $options);

DISTINCT not working with hasMany cakephp

I want to apply DISTINCT query in cakephp 2+ it's working fine but when I BindModel with that model it's not working ?
Here is my code please check it..
$this->User->bindModel(
array(
'hasMany' => array(
'UserPreference' => array(
'className' => 'UserPreference',
'foreignKey' => 'user_id',
'fields' => 'UserPreference.notification_status',
'conditions' => array('UserPreference.notification_status' => 1),
)
)
)
);
$data = $this->User->find('all', array('conditions' => array('app_id NOT ' => '0', 'User.status' => 1), 'fields' => array('DISTINCT User.app_id')));
pr($data); die;
just because I once happened something like this I fix it changing this:
$this->User->bindModel(
array(
'hasMany' => array(
'UserPreference' => array(
'className' => 'UserPreference',
'foreignKey' => 'user_id',
'fields' => 'UserPreference.notification_status',
'conditions' => array('UserPreference.notification_status = 1'),
)
)
)
);

Cakephp counterCache multiple counterScope - Logical issue

Problem:
I have two models: Dealer, Testdrive (Testdrive belongs to Dealer through dealer_id). I want to show real time statistics about the dealers: total (Testdrive.active = 1), processed (Testdrive.active = 1 && Testdrive.processed = 1) ...
I have approx 100 dealers and 10000 testdrives. The count based sql takes about 10 sec (inefficient). Now i have a cronjob that runs every hour but I don't have real time stats.
I tried something like this:
var $belongsTo = array(
'Dealer' => array(
'className' => 'Dealer',
'foreignKey' => 'dealer_id',
'counterCache' => 'active',
'counterScope' => array('Testdrive.active' => 1),
'conditions' => '',
'fields' => '',
'order' => ''
),
'Dealer' => array(
'className' => 'Dealer',
'foreignKey' => 'dealer_id',
'counterCache' => 'processed',
'counterScope' => array('Testdrive.active' => 1, 'Testdrive.processed' => 1),
'conditions' => '',
'fields' => '',
'order' => ''
)
);
... but i overwritten the belongsTo => 'Dealear' value.
Can I have an array of counterCache with an array of counterScope?
var $belongsTo = array(
'Dealer' => array(
'className' => 'Dealer',
'foreignKey' => 'dealer_id',
'counterCache' => array('active', 'processed'),
'counterScope' => array('active' => array('Testdrive.active' => 1), 'processed' => array('Testdrive.active' => 1, 'Testdrive.processed' => 1)),
'conditions' => '',
'fields' => '',
'order' => ''
),
);
There's (now) an example of this in the documentation. Applied to the example in the question that would be:
class TestDrive extends AppModel {
public $belongsTo = array(
'Dealer' => array(
'counterCache' => array(
'active' => array(
'TestDrive.active' => 1
),
'processed' => array(
'TestDrive.active' => 1,
'TestDrive.processed' => 1
)
)
)
);
}
Note there's no need to define keys with default values (className, foreignKey etc.).

CakePHP SQL Error

Im trying to do a purge of records in a database though when I made my query and associations it seems to not want to do it correctly. I got the following error and Im confused as to why this is occurring:
SQL Error: 1054: Unknown column 'GuardiansStudents.student_id' in 'where clause'
The query that gets displayed afterwards is the following:
Query: SELECT `User`.`id`, `Guardian`.`id`
FROM `guardians` AS `Guardian`
LEFT JOIN `users` AS `User` ON (`Guardian`.`user_id` = `User`.`id`)
WHERE `GuardiansStudents`.`student_id` IS NULL
AND `User`.`active` = 1 AND `User`.`changeapprovalneeded` = 0
I also have the following associations in the Guardian model, not sure if Im doing this properly, and possibly this is where the error is occurring:
class Guardian extends AppModel {
var $name = 'Guardian';
//The Associations below have been created with all possible keys,
// those that are not needed can be removed
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
var $hasAndBelongsToMany = array(
'Student' => array(
'className' => 'Student',
'joinTable' => 'guardians_students',
'foreignKey' => 'guardian_id',
'associationForeignKey' => 'student_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
This is the code to do the purge function:
function manager_purgebygrade() {
ini_set('max_execution_time','120');
$this->layout = "manager";
$this->User->recursive = 0;
$grades = $this->User->Student->Grade->getDropDownList();
$this->set(compact('grades'));
//debug($this->data);
if(!empty($this->data['User']['grade_id']))
{
//$this->User->bindModel(array())
$users = $this->User->find(
'list',
array(
'fields' => array(
'User.id'
),
'conditions' => array(
'Student.grade_id' => $this->data['User']['grade_id']
),
'recursive' => 0
)
);
//debug($users);
$this->User->deleteAll(array('User.id' => $users), true);
$this->User->Guardian->bindModel(
array('hasOne' => array('GuardiansStudents')));
$guardianswithnostudents = $this->Guardian->deleteGuardiansWithNoStudent();
$guardians = $this->User->Guardian->find(
'list',
array(
'fields' => array(
'User.id',
'User.id'
),
'conditions' => array(
'GuardiansStudents.student_id' => null,
'User.active' => 1,
'User.changeapprovalneeded' => 0
),
'recursive' => 1
)
);
$this->User->deleteAll(array('User.id' => $guardians), true);
$this->set(compact('users','guardians','guardianswithnostudents'));
}
}
Hopefully someone can point me in the right direction I would greatly appreciate it :).
Your where clause:
WHERE `GuardiansStudents`.`student_id` IS NULL
is using table GuardiansStudents that appears nowhere in the from clause or join clause.
the model is GuardiansStudent, not GuardiansStudents.

Categories