CakePHP多级模型关系中的自定义搜索

时间:2011-12-02 07:54:40

标签: model pagination cakephp-2.0

我希望有人可以对这个问题有所了解。我已经阅读了大量的stackoverflow文档,蛋糕文档,作品,我似乎无法解决这个问题。我的模型关系如下:

  • 马属于供应商
  • 马属于很多
  • 供应商有很多马
  • Lot hasMany Sale
  • Lot hasMany Withdrawal

然后,我列出所有的Lots并显示一个表,包括Horse,Vendor,Lot number等。这样工作正常,事实上使用Paginator :: Sort方法我甚至可以排序为Vendor.name ASC或DESC ,告诉我这些关联是正确的。

我不能 - 但是 - 似乎根据与供应商的任何字段匹配来操纵搜索结果。例如,如果在我的分页设置中,我会执行以下操作:

'conditions' => array('Vendor.name' => 'Simon')...

我得到一个SQL错误,即Vendor.name列不存在,但是如果我删除了这个条件约束,然后我评估了SQL,那么肯定会有。

还应该说我正在使用unbindModel()和bindModel()方法来动态创建hasOne关系以获得最佳的MySQL开销,这并没有导致手头的问题,就像以前一样。

这是我在var_dump()分页结果时得到的第一行:

'Vendor' => 
    array
      'id' => string '2' (length=1)
      'name' => string 'ALDORA STUD' (length=11)
      'surname' => string '' (length=0)
      'address' => string '' (length=0)
      'tel' => string '' (length=0)
      'fax' => string '' (length=0)
      'email' => string '' (length=0)
      'url' => string '' (length=0)
      'comments' => string '' (length=0)
      'created' => string '0000-00-00 00:00:00' (length=19)
      'modified' => string '0000-00-00 00:00:00' (length=19)
      'modified_by' => string '0' (length=1)
  'Withdrawal' => 
    array
      'id' => null
  'Sale' => 
    array
      'id' => null
      'catalogue_id' => null
      'lot_id' => null
      'purchaser' => null
      'amount' => null
      'notes' => null
      'date' => null

我省略了很多行,但你可以清楚地看到供应商作为一个hasOne关系被发送回Lot,我正在工作的控制器。

如果它有帮助,我使用此代码解除绑定并重新绑定模型:

        $this->Lot->unbindModel(array(
            'hasOne' => array('Horse'),
            'hasMany' => array('Withdrawal', 'Update', 'Sale'),
            'belongsTo' => array('Catalogue')
        ));

        $this->Lot->Horse->unbindModel(array(
            'belongsTo' => array('Vendor', 'Lot')
        ));

        $this->Lot->Horse->Vendor->unbindModel(array(
            'hasMany' => array('Horse')
        ));

        $this->Lot->bindModel(array(
            'hasOne' => array(
                'Catalogue' => array(
                    'foreignKey' => false,
                    'conditions' => array('Catalogue.id = Lot.catalogue_id')
                ),
                'Horse' => array(
                    'foreignKey' => false,
                    'conditions' => array('Horse.id = Lot.horse_id')
                ),
                'Vendor' => array(
                    'foreignKey' => false,
                    'conditions' => array('Vendor.id = Horse.vendor_id'),
                ),
                'Withdrawal' => array(
                    'foreignKey' => false,
                    'conditions' => array('Withdrawal.lot_id = Lot.id'),
                    'fields' => array('id')
                ),
                'Sale' => array(
                    'foreignKey' => false,
                    'conditions' => array('Sale.lot_id = Lot.id')
                )
            )
        ));

        $this->Lot->contain(array('Sale', 'Catalogue', 'Withdrawal', 'Horse', 'Vendor'));

我的分页符调用如下所示:

$this->paginate = array(
                    'contain' => array('Sale', 'Catalogue', 'Withdrawal', 'Horse', 'Vendor'),
                    'conditions' => array('Vendor.name' => 'Somerset Stud'),
                    'maxLimit' => ($this->params['ext'] == 'csv' ? 1000 : 25),
                    'limit' => ($this->params['ext'] == 'csv' ? 1000 : 25),
                );

当我收到列Vendor.name不存在的错误时。 如果有人可以分享一些提示和想法,我会永远感激。

亲切的问候, 西蒙

1 个答案:

答案 0 :(得分:0)

从我所看到的你不是供应商控制器/型号,而是其他一些型号。

$this->paginate = array(
                  'contain' => array('Sale', 'Catalogue', 'Withdrawal','Horse',
                  'Vendor'  => array('conditions' => array('Vendor.name'=>'Stu'),
                                     'order'      => array(),
                                     'fields'     => array())
                );

以上代码应该有效。可能存在语法错误,但我希望你能得到我的意思

以下是本书http://book.cakephp.org/view/1323/Containable

的示例
$this->Post->find('all', array('contain' => array(
    'Comment' => array(
        'conditions' => array('Comment.author =' => "Daniel"),
        'order' => 'Comment.created DESC'
    )
)));