ynamics/relatedsearchbehavior

简化在 CGridView 中搜索关系以及使用关系的操作

安装: 73

依赖: 0

建议者: 0

安全: 0

星星: 2

关注者: 3

分支: 1

开放问题: 2

类型:yii-extension

1.27 2021-06-11 12:42 UTC

This package is auto-updated.

Last update: 2024-09-13 00:12:11 UTC


README

Yii 扩展 - RelatedSearchBehavior

  1. 需求
  2. 论坛
  3. 用法
  4. 历史
  5. 资源

使用此行为简化创建与相关表相关联的 CGridView 或从相关表获取字段。它神奇地添加了所需的 'with' 子句,并提供了关系记录字段的自定义别名。

实时演示

使用 KeenActiveDataProvider 扩展来限制对数据库的请求数量。

需求

适用于 Yii 1.1.12-1.1.26 版本。

论坛

关于此扩展的论坛主题 可在此找到。

用法

要使用此扩展,您必须执行以下 5 个步骤

  1. "安装" RelatedSearchBehavior;
  2. 更新模型的 search() 方法;
  3. 添加/更新 'behaviors()' 方法;
  4. 将搜索字段添加到模型规则中作为安全字段;
  5. 将搜索字段用作 CGridView 中的任何其他字段。

以下是这些步骤的详细信息

1. "安装" RelatedSearchBehavior;

安装就像将位置添加到 Yii 配置文件 (main.php) 的 'import' 配置中一样简单

return array(
    [...]
    'import'=>array(
        [...]
        'ext.KeenActiveDataProvider',
        'ext.RelatedSearchBehavior',
    ),

在上面的例子中,RelatedSearchBehavior 文件被放置在 extensions 目录中。

2. 更新模型的 search() 方法;

更新 ActiveRecord::search() 的重载。以下示例显示了如何设置默认的搜索顺序。您可以在第二个数组中设置任何由 CActiveDataProvider 接受的参数(如分页)。因此,将以下代码替换为

return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    'sort'=>array(
      'defaultOrder'=>'title ASC',
    )
));

为以下代码(我更喜欢使用如 '$sort' 这样的中间变量来提高可读性和灵活性)

$sort=array(
    'defaultOrder'=>'title ASC',
);
return $this->relatedSearch(
    $criteria,
    array('sort'=>$sort)
);

在上面的示例中,'title' 可以是您定义的相关字段之一。

3. 添加/更新 'behaviors()' 方法

将行为附加到 CActiveRecord 并指定相关字段。

function behaviors() {
    return array(
        'relatedsearch'=>array(
             'class'=>'RelatedSearchBehavior',
             'relations'=>array(
                  'serial'=>'device.device_identifier',
                  'location'=>'device.location.description',

                 'fieldwithdifferentsearchvalue'=>array(
                     'field'=>'device.displayname',
                     'searchvalue'=>'deviceid'
                  ),


                 'mylocalreference'=>'field.very.far.away.in.the.relation.tree',
             ),
         ),
    );
}
4. 将搜索字段添加到模型规则中作为安全字段;
public function rules() {
    return array(
        [...]
        array('serial,location,deviceid','safe','on'=>'search'),
    );
}
5. 将搜索字段用作 CGridView 中的任何其他字段。

对于 CGridView 列指定,您可以为列简单地使用 'serial'(不需要做 'name'=>..., 'filter'=>..., 'value'=>...)。

示例

$this->widget('zii.widgets.grid.CGridView', array(
  [...]
  'columns'=>array(
      [...]
      'serial',
      'location',
  )
));
6. 要使用 "autoScope"

Autoscope 允许您使用范围搜索字段,而无需自己声明该范围。

例如,您可以使用此

MyModel::model()->location('Belgium')->findAll();

之前,您必须

  1. 将 RelatedSearchBehavior 添加到您的 CActiveRecord 的行为中(已在前面步骤中完成,
  2. 将以下通用代码添加到您的 CActiveRecord 模型中。
public function __call($name,$parameters) {
    try {
        return parent::__call($name,$parameters);
    } catch (CException $e) {
        if(preg_match(
            '/'.Yii::t(
                'yii',
                quotemeta(
                    Yii::t(
                        'yii',
                        '{class} and its behaviors do not have a method or closure named "{name}".'
                        )
                    ),
                    array('{class}'=>'.*','{name}'=>'.*')
                )
                .'/',$e->getMessage())) {
                return $this->autoScope($name, $parameters);
            } else {
                throw $e;
            }
        }
    }

您允许提供所有常规比较参数

MyModel::model()->location($searchvalue,$partialMatch,$operator,$escape)->findAll();

默认值与 compare: autoscope(,false,"AND",false) 相同。

这在复杂嵌套条件下很有用,对于像上述简单的搜索这样的简单搜索则不太有用。

7. 在CSort属性中使用关系进行排序。

'CSort' 允许您指定如Yii文档中所述的'虚拟属性'进行排序。[链接](https://yiiframework.cn/doc/api/1.1/CSort#attributes-detail)。在没有RelatedSearchBehavior的情况下,您必须确保包含在搜索条件中使用的关联。有了RelatedSearchBehavior,您就不必担心这个问题 - 扩展会为您处理(自1.16版起)。

$sort=array(
    'defaultOrder'=>'title ASC',
    'attributes'=>
        array(
            'price'=>array(
                'asc'=>'item.price',
                'desc'=>'item.price DESC',
                'label'=>'Item Price'
            ),
        ),
    );
return $this->relatedSearch(
    $criteria,
    array('sort'=>$sort)
);

首选的方法是使用为RelatedSearchBehavior定义的属性,但在组合排序条件下这可能会很有用。

$sort=array(
    'defaultOrder'=>'title ASC',
    'attributes'=>
        array(
            'groupprice'=>array(
                'asc'=>'item.group, item.price',
                'desc'=>'item.group DESC, item.price DESC',
                'label'=>'Item Price'
            ),
        ),
    );
return $this->relatedSearch(
    $criteria,
    array('sort'=>$sort)
);
8. exactSearchAttributes

当在CActiveRecord中定义了CActiveRecord::exactSearchAttributes时,那里列出的属性默认情况下是精确匹配,而不是部分匹配。这在与表组合使用时特别有用,并且适用于列(不仅仅是关联)。例如,ID不应该部分匹配,id "1" 也会匹配10..19,21,31等。要求精确匹配还可以提高搜索性能,因为当使用索引时这更合适。

示例

public function exactSearchAttributes() {
    return [
        'is_active',
        'context_id',
        'entity_id',
        'type_id',
    ];
}

在上面的例子中

  • is_active 是布尔值,所以精确匹配在这里是完美的;
  • context_id 是一个与UI中的描述相匹配的概念;
  • entity_id 匹配某些实体,也显示为特定于实体的标签;
  • type_id 定义了记录的类型,并且也匹配某些标签。
9. 小贴士与注意事项
  • 如果您喜欢RelatedSearchBehavior,您可以通过创建或更新Gii模板来自动生成它。
  • 如果您使用'ERememberFiltersBehavior',在获取dataProvider之前必须设置rememberScenario - 否则,在排序子句中关系将不会解析。所以您编写
$model->rememberScenario="admin";
$dataProvider=$model->search();

这是作者使用此扩展的项目中的搜索方法。所有模型都从YActiveRecord扩展,而YActiveRecord又从CActiveRecord扩展并实现了对默认CActiveRecord功能的几个扩展。它实现了以下搜索方法(RelatedSearchBehavior必须添加到模型类本身)

/**
 * Search method valid for all Active Records (with RelatedSearchBehavior)
 *
 * @return KeenActiveDataProvider
 */
public function search() {
    $criteria=new CDbCriteria();
    $t=$this->getTableAlias(false, false);
    $ds=$this->getDbConnection()->getSchema();

    $columns=$this->getMetaData()->columns;
    //$relations=$this->relations;
    foreach ($this->getSafeAttributeNames() as $attribute) {
        $value=$this->{$attribute};
        if ($value==='=') {
            $value=array(null,'');
        }
        if (is_array($value)&&!empty($value)||(!is_array($value)&&"$value" !== "")) {
            if (isset($columns[$attribute])) {
                if (in_array($attribute,$this->exactSearchAttributes())) {
                    Yii::trace("Exact match required for $attribute");
                }
                $criteria->compare($ds->quoteColumnName("$t.$attribute"),
                        $value,
                        !$columns[$attribute]->isForeignKey
                        &&!in_array($attribute,$this->exactSearchAttributes())
                );
            }
        /**
         * Sample code to handle exceptions (fields that are not in
         * relations).
         * ```php
         * else if (!isset($relations[$attribute])) {
         *   // Not a related search item -> do something else
         *   $this->compareProperty($attribute, $value,true);
         * }
         * ```
         */
        }
    }
    // $criteria->together=true;

    return $this->relatedSearch($criteria
        //,array('sort'=>array('defaultOrder'=>$this->getTableAlias(true,false).'.entity_id DESC'))
    );
}

/**
 * Provides the list of attributes for which an exact search is
 * needed and not a partial search.
 * (typical: keys, enums, etc.
 * @return string[]
 */
public function exactSearchAttributes() {
    return [];
}

历史

查看RelatedSearchbehavior.php以了解版本的简要描述

资源