简体   繁体   中英

How to search for records in Yii using NULL search criteria

Say I have Product model which has Category property and I want to pull all such products where category is null using search() function.

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

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

By examining the generated SQL I see that it does not work, category is not being mentioned in the query at all. What is the best way to do it?

Also how to search records which have certain property set to NULL OR Certain value

1st variant:

// 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();

2nd variant (preffered):

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

Assigning null value to a property does not work as it is not recorded by Yii: initial value of properties is null and Yii does not track modified properties (which is a bit annoying).

The work around here is to use it like this:

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

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

Note that if you want to search for more advanced Category IS NULL OR Category IN (1, 2, 3) the expected way to do it:

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

won't work as Yii blindly puts it all into a single IN statement:

Category IN (NULL, 1, 2, 3)

Work around here is more complicated as it requires extra code in your model search method:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM