在 Yii 2.0 中,核心验证器:unique (唯一性) 支持多个模型与变量的实现
1、涉及至第 1 张表,企鹅号的文章:cpa_qq_article,需要验证其字段:title 的唯一性,表结构如图1
2、涉及至第 2 张表,渠道的应用的任务:cpa_channel_app_task,字段:task_id 与 企鹅号的文章的字段:task_id 存在关联关系(多对一),字段:channel_app_source_uuid 为条件(变量、请求参数),字段:status 为条件(常量),表结构如图2
3、filter:用于检查输入值唯一性必然会进行数据库查询,而该属性为用于进一步筛选该查询的过滤条件。样式为 function ($query) 的匿名函数, $query 参数为你希望在该函数内进行修改的 Query 对象。模型中的验证规则声明如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /** * {@inheritdoc} */ public function scenarios() { $scenarios = parent::scenarios(); $scenarios [self::SCENARIO_CREATE] = [ 'group_id' , 'article_category_id' , 'title' , 'author' , 'source_article_id' ]; return $scenarios ; } /** * @inheritdoc */ public function rules() { $rules = [ [ 'title' , 'unique' , 'filter' => function ( $query ) { /* @var $query ChannelAppTaskQuery */ $query ->joinWith( 'channelAppTask' , false)->andWhere([ChannelAppTask::tableName() . '.status' => ChannelAppTask::STATUS_PLATFORM_PUBLISHED]); }, 'on' => self::SCENARIO_CREATE], ]; $parentRules = parent::rules(); return ArrayHelper::merge( $rules , $parentRules ); } /* * 声明了一个渠道的应用的任务关联 */ public function getChannelAppTask() { return $this ->hasOne(ChannelAppTask::className(), [ 'task_id' => 'task_id' ]); } |
4、验证请求参数时,生成的 SQL 如下:
1 | SELECT EXISTS(SELECT `cpa_qq_article`.* FROM `cpa_qq_article` LEFT JOIN `cpa_channel_app_task` ON `cpa_qq_article`.`task_id` = `cpa_channel_app_task`.`task_id` WHERE (`cpa_qq_article`.`title`='未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。') AND (`cpa_channel_app_task`.`status`=6)) |
5、请求参数中,存在 channel_app_source_uuids 字段,其值为数组:[“8d72b7cc2ac911eab85a54ee75d2ebc1”, “18cf06d22ac911eaa31854ee75d2ebc1”],需要将 channel_app_source_uuids 的值做为条件应用于唯一性验证的查询条件中。在执行模型的验证之前,赋值给应用的全局参数变量 Yii::$app->params。如图3
1 2 | $requestParams = Yii:: $app ->getRequest()->getBodyParams(); Yii:: $app ->params[ 'channelAppSourceUuids' ] = $requestParams [ 'channel_app_source_uuids' ]; |
6、现在可在验证规则中使用 Yii::$app->params,模型中的验证规则声明调整如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * @inheritdoc */ public function rules() { $rules = [ [ 'title' , 'unique' , 'filter' => function ( $query ) { /* @var $query ChannelAppTaskQuery */ $query ->joinWith( 'channelAppTask' , false)->andWhere([ 'and' , [ 'in' , ChannelAppTask::tableName() . '.channel_app_source_uuid' , Yii:: $app ->params[ 'channelAppSourceUuids' ]], [ChannelAppTask::tableName() . '.status' => ChannelAppTask::STATUS_PLATFORM_PUBLISHED]]); }, 'on' => self::SCENARIO_CREATE], ]; $parentRules = parent::rules(); return ArrayHelper::merge( $rules , $parentRules ); } |
7、验证请求参数时,生成的 SQL 如下,请求参数已经应用于查询条件中,符合预期
1 | SELECT EXISTS(SELECT `cpa_qq_article`.* FROM `cpa_qq_article` LEFT JOIN `cpa_channel_app_task` ON `cpa_qq_article`.`task_id` = `cpa_channel_app_task`.`task_id` WHERE (`cpa_qq_article`.`title`='未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。') AND ((`cpa_channel_app_task`.`channel_app_source_uuid` IN ('8d72b7cc2ac911eab85a54ee75d2ebc1', '18cf06d22ac911eaa31854ee75d2ebc1')) AND (`cpa_channel_app_task`.`status`=6))) |
8、核心验证器:unique (唯一性) 支持多个模型与变量的实现,验证失败时,响应如下,如图4
1 2 3 4 | { "code": 226004, "message": "数据验证失败:标题的值\"未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。\"已经被占用了。" } |
近期评论