2012-10-09 127 views
3

假设我有具有Category属性的产品模型,并且我想使用search()函数将所有类别为nu​​ll的产品拉出。如何使用NULL搜索条件搜索Yii中的记录

$productSearch = clone Product::model(); 
$productSearch->Category = null; 

$products = $productSearch->search()->getData(); 

通过检查生成的SQL我看到它不工作,类别不被查询涉及。什么是最好的方式来做到这一点?

而且如何寻找具有一定的属性设置记录NULL或者特定值

回答

0

分配空值的属性,因为它没有被Yii记录不起作用:属性初始值是零和的Yii不跟踪修改后的属性(这有点烦人)。

在这里的工作就是用这样的:

$productSearch = clone Product::model(); 
$productSearch->Category = array(null); 

$products = $productSearch->search()->getData(); 

需要注意的是,如果你想寻找更多的先进Category IS NULL OR Category IN (1, 2, 3)预期的方式做到这一点:

$productSearch->Category = array(null, 1, 2, 3); 

韩元” t工作作为Yii一味地把它全部纳入一个单一的声明:

Category IN (NULL, 1, 2, 3) 

工作在这里是因为它需要你的模型搜索方法额外的代码更复杂:

public function search() 
{ 
    $criteria = new CDbCriteria; 

    // Work around of inability of Yii to handle IS NULL OR IN() conditions 
    if (is_array($this->Category) && count($this->Category) > 1) 
    { 
     $hasNull = false; 
     $values = array(); 
     foreach ($this->Category as $value) 
     { 
      if (is_null($value)) 
      { 
       $hasNull = true; 
      } 
      else 
      { 
       array_push($values, $value); 
      } 
     } 

     $condition = array(); 
     if ($hasNull) array_push($condition, 'Category IS NULL'); 
     if (count($values)) array_push($condition, "Category IN ('" . implode("', '", $values) . "')"); 

     $criteria->addCondition(implode(' OR ', $condition)); 
    } 
    else 
    { 
     $criteria->compare('Category', $this->Category); 
    } 

    // other search criterias ... 

    return new CActiveDataProvider($this, array(
     'criteria'=>$criteria, 
    )); 

} 
5

1变种:

// use search scenario, not clone model with metadata 
$productSearch = new Product('search'); 
$productSearch->unsetAttributes(); 

// get CActiveDataProvider 
$dataProvider = $productSearch->search(); 
// Add null condition 
$dataProvider->criteria->addCondition('Category is null'); 
// Get data - first 10 rows 
$products = $dataProvider->getData(); 

第二个变种(参访):

$products = Product::model()->findAll('Category is null'); 
+0

问题的情景是默认值仍然分配给模型,意思是你有状态默认激活它将只搜索活动记录,但你没有意识到它。据我所知,无论选择哪种场景。 –

+0

至于findAll我不喜欢暴露在控制器中的SQL,有点乱。 –

+0

@AlexeiTenitski,$ productSearch-> unsetAttributes(); - 它也重置默认值,如果你想使用黑客,欢迎你。 – Sergey