【问题标题】:How to search for records in Yii using NULL search criteria如何使用 NULL 搜索条件在 Yii 中搜索记录
【发布时间】:2012-10-09 21:53:11
【问题描述】:

假设我有具有 Category 属性的 Product 模型,我想使用 search() 函数提取所有类别为 null 的此类产品。

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

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

通过检查生成的 SQL,我发现它不起作用,查询中根本没有提到类别。最好的方法是什么?

还有如何搜索将某些属性设置为NULL OR某个值的记录

【问题讨论】:

    标签: php model yii


    【解决方案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');
    

    【讨论】:

    • 场景的问题是默认值仍然分配给模型,这意味着您的状态默认为活动,它将仅搜索活动记录而您没有意识到这一点。据我所知,无论选择什么场景。
    • 至于 findAll 我不想在控制器中公开 sql,有点不整洁。
    • @AlexeiTenitski, $productSearch->unsetAttributes(); - 它也重置默认值,好吧,如果你想使用黑客,欢迎你。
    • 不知道 unsetAttributes 但它听起来像使用克隆一样 hackish。
    【解决方案2】:

    为一个属性分配空值不起作用,因为它没有被 Yii 记录:属性的初始值为 null 并且 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);
    

    行不通,因为 Yii 盲目地将所有内容放在一个 IN 语句中:

    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,
        ));
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      • 2021-02-17
      相关资源
      最近更新 更多