views:

84

answers:

4

I have three models linked in this manner: Item->Order->Payment

Order hasMany Item
Order hasOne Payment

Now, I am paginating Items and want to add a condition in it to find only items of that order which has payment of a particular id. I hope that makes sense :P

I added the condition as:

array('Payment.id'=>$id)

but it doesn't work. Obviously cause Payment is not associated with Item.

So, how can I go about this?

A: 

Why don't you add a condition:

array('Order.payment_id'=>$id)

I think this should work.

Nik
Well, Order doesn't have payment_id... Payment has order_id in this case as Payment belongsTo Order and Order hasOne Payment
aadravid
+1  A: 

I am new to cakephp, maybe I am completily wrong but as I understand it you can use other models in your controller with the $uses variable. First make a query on payment model to get your order id, than you can use this id to find the corresponding items.

$uses=array('Item','Order','Payment');
$order_id=$this->Payment->find('first',array('fields'=>'order_id','conditions'=>array('id'=>$payment_id)));
$items=$this->Item->find('all',array('conditions'=>array('order_id'=>$order_id)));

I hope it help.

sipiatti
it would help, just one thing: $order_id['Payment']['order_id'] otherwise it will return multidimensional array and the $items will be empty
Nik
this is fine but how can do this with pagination?
aadravid
you can use $limit and $page as find parameters and also you can sort it. you need to build up your own way to solve the paginating as the built-in paginator has its own barriers...check this out: http://book.cakephp.org/view/73/Retrieving-Your-Data#find-449
sipiatti
A: 

If you specify that you want two levels of recursion this should work. Im assuming you have

in Payment.php

//recursion level 1
var $belongsTo = array('Order');

in Order.php

//recursion level 2
var $hasMany = array('Items')

You are right that for paginate to work you must query the model you wish to page and sort the lists by.

in PaymentController.php

//Query two levels deep, so the $payment['Order']['Item'][0-n] will be present
var $paginate = array('recursive' => 2);

Note this method does generate another query for each row to retrieve items.

Lincoln B
i have tried all levels of recursive values but strangely it didn't work... what you have assumed and your solution is right but i don't know whats going wrong.
aadravid
A: 

Make sure the debug level in app/config/core.php is set to 2 to see the database calls.

1) You can use Containable behaviour, in which case you need to put this in your Item model:

var $actsAs = array('Containable');

and this into your Items controller:

$items = $this->Item->find('all'
   , array (
      'contain' => array('Order' => array('Payment'))
      , 'conditions' => array('Payment.id' => $paymentId)
   )
)

However I suspect that that will do a left join onto the Payments table (as its a hasMany relationship). So you won't filter Items in any way.

2) If you can't get contains to work then I often use explict joins (read this bakery article by nate on joins) in my find queries. So in your Items controller you'd have:

$items = $this->Item->find('all'
   , array (
      , 'joins' => array(
         array(
            'table' => 'payments'
            , 'alias' => 'Payment'
            , 'type' => 'INNER'
            , 'conditions' => array(
                'Option.id = Payment.option_id'
            )
         )
      )
      , 'conditions' => array('Payment.id' => $paymentId)
   )
)

You may also need to specify the join onto the options table.

icc97
this is more like it... will try it out and let you know! thanks a lot.
aadravid