Cakephp bug : in paginator joins generated query - php

When below code below it generate query with single quote in join query
$this->Paginator->settings = array(
'joins' => array(
array(
'table' => 'businesses_categories',
'alias' => 'BusinessesCategory',
'type' => 'LEFT',
'conditions' => array('Business.id' => 'BusinessesCategory`.`business_id'),
),
array(
'table' => 'categories',
'alias' => 'Category',
'type' => 'LEFT',
'conditions' => array('BusinessesCategory.category_id' => 'Category.id'),
),
),
'conditions' => array(
'Category.id' => 24),
'limit' => 10
);
$businesses = $this->Paginator->paginate('Business');
I have added query that's generated by above paginator query. query works fine, when i use ON (Business.id = BusinessesCategory.business_id) instead of ON (Business.id = 'BusinessesCategory.business_id')
how do i fix this. so, it does not include single quote on values
SELECT `Business`.`id`,
`Business`.`state`,
`Business`.`slug`,
`Business`.`city`,
`Business`.`suburb`,
`Business`.`user_id`,
`Business`.`business_name`,
`Business`.`business_address`,
`Business`.`business_postal`,
`Business`.`business_postal_id`,
`Business`.`business_phone`,
`Business`.`business_phone1`,
`Business`.`business_phone2`,
`Business`.`business_email`,
`Business`.`business_website`,
`Business`.`business_details`,
`Business`.`business_openinghours`,
`Business`.`business_service`,
`Business`.`business_addtionalinfo`,
`Business`.`business_lat`,
`Business`.`business_lng`,
`Business`.`identity`,
`Business`.`status`
FROM `yuldicom`.`businesses` AS `Business`
LEFT JOIN `yuldicom`.`businesses_categories` AS `BusinessesCategory` ON (`Business`.`id` = 'BusinessesCategory`.`business_id')
LEFT JOIN `yuldicom`.`categories` AS `Category` ON (`BusinessesCategory`.`category_id` = 'Category.id')
WHERE `Category`.`id` = 24 LIMIT 10

Here you go :--
$this->Paginator->settings = array(
'joins' => array(
array(
'table' => 'businesses_categories',
'alias' => 'BusinessesCategory',
'type' => 'LEFT',
'conditions' => array('Business.id=BusinessesCategory.business_id'),
),
array(
'table' => 'categories',
'alias' => 'Category',
'type' => 'LEFT',
'conditions' => array('BusinessesCategory.category_id=Category.id'),
),
),
'conditions' => array(
'Category.id' => 24),
'limit' => 10
);
$businesses = $this->Paginator->paginate('Business');

Related

Custom query pagination in cakephp

I have a query as below in controller with multiple joins
$deals = $this->Deals->find('all', array(
'fields' => array(
'Deals.id',
'Deals.deed_amount',
'Deals.other_amount',
'Deals.cash_amount',
'Deals.total_amount',
'Deals.client_id',
'Deals.project_id',
'Deals.property_id',
'Deals.properties_flat_id',
'Deals.date',
'Deals.status',
'Deals.invoice_no',
'Deals.remain_cash_amount',
'Deals.remain_deed_amount',
'Deals.remain_other_amount',
'Deals.remain_deed_amount',
'Property.name',
'Client.name',
'PropertyFlat.name',
'PropertyFlat.status'
),
'joins' => array(
array(
'table' => 'properties',
'alias' => 'Property',
'type' => 'LEFT',
'conditions' => array(
'Deals.property_id = Property.id'
)
),
array(
'table' => 'clients',
'alias' => 'Client',
'type' => 'LEFT',
'conditions' => array(
'Deals.client_id = Client.id'
)
),
array(
'table' => 'properties_flats',
'alias' => 'PropertyFlat',
'type' => 'LEFT',
'conditions' => array(
'Deals.properties_flat_id = PropertyFlat.id'
)
)
),
// 'conditions'=>$condition
));
I want to add pagination to the view. I tried following
$this->set('deals', $this->Paginator->paginate($deals));
But no use. Please help me in how to add pagination for the custom query. I searched many links but did not get any help.
You can try like this:
$paginate = [
'joins' => array(
array(
'table' => 'properties',
'alias' => 'Property',
'type' => 'LEFT',
'conditions' => array(
'Deals.property_id = Property.id'
)
),
array(
'table' => 'clients',
'alias' => 'Client',
'type' => 'LEFT',
'conditions' => array(
'Deals.client_id = Client.id'
)
),
array(
'table' => 'properties_flats',
'alias' => 'PropertyFlat',
'type' => 'LEFT',
'conditions' => array(
'Deals.properties_flat_id = PropertyFlat.id'
)
)
),
'fields' => array(
'Deals.id',
'Deals.deed_amount',
'Deals.other_amount',
'Deals.cash_amount',
'Deals.total_amount',
'Deals.client_id',
'Deals.project_id',
'Deals.property_id',
'Deals.properties_flat_id',
'Deals.date',
'Deals.status',
'Deals.invoice_no',
'Deals.remain_cash_amount',
'Deals.remain_deed_amount',
'Deals.remain_other_amount',
'Deals.remain_deed_amount',
'Property.name',
'Client.name',
'PropertyFlat.name',
'PropertyFlat.status'
)
];
$this->set('deals', $this->Paginator->paginate($this->Deals->find('all'), $paginate)->toArray());
Firstly, I would recommend to rethink the way you have constructed your query. Why don't you just use the contain() method to retrieve the associated data?
Secondly, You can use custom finders with the paginator. Just create one in your Table class and return constructed query from it and ask the paginator to use it. Read more here. https://book.cakephp.org/3.0/en/controllers/components/pagination.html

cant convert a find all over many records to paginatein cakephp

I cant convert this find all to a paginate statement. The find all works fine as below. Then I converted this to paginate with error
Column not found: 1054 Unknown column 'Lesson.id' in 'on clause'. Not sure what to do as I have done paginate before without issues.
$lessons = $this->find('all', array(
// 'conditions' =>$default_array,
'joins' => array(
array('table' => 'lessons_students',
'alias' => 'LessonStudents',
'type' => 'INNER',
'conditions' => array(
'LessonStudents.student_id' => $studentId,
'LessonStudents.lesson_id = Lesson.id'
)
)
),
'group' => 'Lesson.id',
'order' => array('Lesson.lesson_date' => 'asc'),
));
$this->Paginator->settings = array(
// 'conditions' =>$default_array,
'joins' => array(
array('table' => 'lessons_students',
'alias' => 'LessonStudents',
'type' => 'INNER',
'conditions' => array(
'LessonStudents.student_id' => $id,
'LessonStudents.lesson_id = Lesson.id'
)
)
),
'group' => 'Lesson.id',
'order' => array('Lesson.lesson_date' => 'asc'),
);
$lessons =$this->Paginator->paginate('Student'); //also tried lesson
the join should cal a variable which does work. I solved it this way

Access related models/tables to inner join query in cakephp

I have this inner join query in a paginated model called Application
Application has many AssignedExploration
AssignedExploration belongs to Exploration
Exploration belongs to ExplorationCategory
ExplorationCategory belongs to Season
My query so far is:
$session_condition = array(
'table' => 'assigned_explorations',
'alias' => 'AssignedExploration',
'type' => 'INNER',
'conditions' => array(
'AssignedExploration.application_id = Application.id',
'OR' => array(
array('AssignedExploration.label' => $this->request->named['filter_session'])
)
)
);
I would like to add another query inside the OR that will get applications which has a Season.name = fall
I've tried adding array('Season.name' => 'fall') :
$session_condition = array(
'table' => 'assigned_explorations',
'alias' => 'AssignedExploration',
'type' => 'INNER',
'conditions' => array(
'AssignedExploration.application_id = Application.id',
'OR' => array(
array('AssignedExploration.label' => $this->request->named['filter_session']),
array('Season.name' => 'fall')
)
)
);
But no luck. Seems like Season is not recognized by AssignedExploration.
I would like to nest from AssignedExploration to Exploration to ExplorationCategory and to Season
And I don't have any idea on how to make it thru inner join query via cakephp.
Thanks in advanced.
EDIT: query as of now:
INNER JOIN
`ntc_development`.`assigned_explorations` AS `AssignedExploration` ON (
`AssignedExploration`.`application_id` = `Application`.`id`
AND
`AssignedExploration`.`label` = 'fall'
)
$this->paginate['Application'] = array(
'recursive' => -1,
'joins' => array(
array(
'table' => 'assigned_explorations',
'alias' => 'AssignedExploration',
'type' => 'inner',
'foreignKey' => true,
'conditions' => array('AssignedExploration.application_id = Application.id')
),
array(
'table' => 'seasons',
'alias' => 'Season',
'type' => 'inner',
'foreignKey' => true,
'conditions' => array('Season.id = Application.season_id') # whats your foregin key
),
),
'fields' => array(),
'conditions' => array('Season.name' => 'fail'),
);

left join on cake php 1.3

How to create this query on cakePHP 1.3
SELECT "Redeem_log"."benefit_id", count("Redeem_log"."benefit_id") as JUMLAH FROM "redeem_logs" "Redeem_log"
LEFT JOIN "benefits" "Benefit" ON ("Redeem_log"."benefit_id" = "Benefit"."id")
LEFT JOIN "merchants" "Merchant" ON ("Benefit"."merchant_id" = "Merchant"."id")
LEFT JOIN "merchant_types" "Merchant_type" ON ("Merchant"."merchant_type_id" = "Merchant_type"."id")
WHERE "Redeem_log"."benefit_id" IS NOT NULL AND ("Merchant_type"."merchant_type"='lokal' OR "Merchant_type"."merchant_type"='nasional') GROUP BY "Redeem_log"."benefit_id" ORDER BY "JUMLAH" DESC
I don't want to use belongsTO, hasMany or ect
If I use
var $belongsTo = array(
'Benefit' => array('className' => 'Benefit', 'foreignKey' => 'benefit_id'),
'Merchant' => array('className' => 'Merchant', 'foreignKey' => 'merchant_id')
);
left join is like :
SELECT "Redeem_log"."benefit_id", count("Redeem_log"."benefit_id") as JUMLAH
FROM "redeem_logs" "Redeem_log"
LEFT JOIN "benefits" "Benefit" ON ("Redeem_log"."benefit_id" = "Benefit"."id")
LEFT JOIN "merchants" "Merchant" ON ("Redeem_log"."merchant_id" = "Merchant"."id")
WHERE "Redeem_log"."benefit_id" IS NOT NULL GROUP BY "Redeem_log"."benefit_id"
ORDER BY "JUMLAH" DESC
I would do it this way, the params for the query looks bit scary, but when you look on it in details it makes sense:
$params = array(
'recursive' => -1,
'fields' => array('RedeemLog.benefit_id', 'COUNT(RedeemLog.benefit_id) as JUMLAH'),
'conditions' => array(
array('NOT' => array('RedeemLog.benefit_id' => null)),
array('Merchanttype.merchant_type' => array('lokal', 'nasional')),
),
'joins' => array(
array(
'table' => 'benefits',
'alias' => 'Benefit',
'type' => 'LEFT',
'conditions' => array('RedeemLog.benefit_id = Benefit.id')
),
array(
'table' => 'merchants',
'alias' => 'Merchant',
'type' => 'LEFT',
'conditions' => array('Benefit.merchant_id = Merchant.id')
),
array(
'table' => 'merchant_types',
'alias' => 'Merchanttype',
'type' => 'LEFT',
'conditions' => array('Merchant.merchant_type_id = Merchanttype.id')
),
),
'order' => 'JUMLAH DESC',
'group' => 'RedeemLog.benefit_id',
);
and finaly the cake find
$result = $this->RedeemLog->find('all', $params);
hope it works for you.
Add joins field in params parameter of MOdel::find();
like this
$params = array(
'joins'=>array(
array(
'table'=>'users',
'alias'=>'User',
'type'=>'LEFT/RIGHT/INNER',
'conditions'=>array("$this->Alias.foreignKey=User.pk")
)
)
);

cakephp find all join

$order = $this->Order->find('all', array(
'recursive' => 2,
'conditions' => array(
'Order.date' => $datefrom,
),
'joins' => array(
array(
'table' => 'purchase',
'alias' => 'Purchase',
'conditions'=> array(
'Purchase.pid = Order.pid',
)
),
array(
'table' => 'sales',
'alias' => 'Sales',
'conditions'=> array(
'Purchase.pid = Sales.pid',
)
),
),
));
Why does the above code doesn't select fields from purchase and sales, but only fields from order are returned. What is the necessary things to be added to make all data is returned. Thanks
Try this, I'm not sure if the 'type' and 'foreignKey' keys are required, but I typically include them when using the 'joins' key. Also I'm assuming the 'pid' is the correct foreign key.
$order = $this->Order->find('all', array(
'recursive' => -1,
'conditions' => array(
'Order.date' => $datefrom,
),
'joins' => array(
array(
'table' => 'purchase',
'alias' => 'Purchase',
'type' => 'INNER',
'foreignKey' => 'pid',
'conditions'=> array(
'Order.pid = Purchase.pid',
)
),
array(
'table' => 'sales',
'alias' => 'Sales',
'type' => 'INNER',
'foreignKey' => 'pid',
'conditions'=> array(
'Sales.pid = Purchase.pid',
)
),
),
));
If you already have relationships set up in the model, change the 'recursive' key to -1.
Just an idea,
'table' => 'purchase',
'alias' => 'Purchase',
isn't a typo, is it? Because I think, the usual name for the table according to cake-conventions would be 'purchases'... But I don't know your tables of course... ;)
First you need to create an association in Order Model file
Model:
public $hasMany = array(
'purchase' => array(
'className' => 'purchase',
'foreignKey' => 'pid',
'dependent' => true,
'counterQuery' => 'true'
),
'sales' => array(
'className' => 'sales',
'foreignKey' => 'pid',
'dependent' => true,
'counterQuery' => 'true'
),
);
Controller:
$order = $this->Order->find('all', array(
'recursive' => 2,
'conditions' => array(
'Order.date' => $datefrom,
)
);
Now you can get Order, Purchase and Sales related records.
Enjoy...
Controller::loadModel('User');
Controller::loadModel('Answer');
Controller::loadModel('Influence');
$users = $this->User->find('all', array('joins' => array(
array(
'table' => 'answers',
'alias' => 'Answer',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array('Answer.user_id = User.id'),
),
array(
'table' => 'influences',
'alias' => 'Influence',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array(
'Influence.user_id=Answer.user_id',
)
)
),'fields' => array(
'Answer.is_correct',
'Answer.answer',
'Answer.date as answered_date',
'Influence.signups',
'Influence.clicks',
'User.first_name',
'User.last_name',
'User.email',
'User.phone',
'User.flybuys' )
));
In order to get fields from other tables You should specify the fields you want.

Categories