Yii使用join()+one()无法访问自定义属性,能否以模型形式获取?
问题
我不确定这是不是Yii Active Record的正常行为,现有如下代码:
$post = Post::find() ->alias('p') ->select(['p.*', 'COUNT(c.id) AS comment_count']) ->join('LEFT JOIN', 'comments c', 'p.id = c.post_id') ->groupBy('p.id') ->one();
我无法通过$post->comment_count访问这个统计值,但使用->asArray()->one()后,可以通过$post['comment_count']访问。有没有办法在返回Post模型实例的同时,依然能访问comment_count?我需要用这个属性做验证,示例如下:
// 上述代码得到的$post if ($post->comment_count != 0) { throw new UnprocessableEntityHttpException('无法删除带有评论的文章'); } return $post->delete();
解决方案
这是Yii ActiveRecord的正常行为:默认情况下,ActiveRecord只会将数据表中定义的字段作为模型属性,自定义查询出来的comment_count不在表结构里,所以模型实例不会自动识别这个属性。要解决这个问题,有两种简单的方法:
方法一:在Post模型中声明公共属性
直接在Post类里添加一个公共属性,对应查询中的comment_count:
class Post extends ActiveRecord { public $comment_count; // 模型其他代码... }
方法二:重写attributes()方法
如果需要更规范的方式,或者有多个自定义查询属性,可以重写模型的attributes()方法,将自定义属性加入到属性列表中:
class Post extends ActiveRecord { public function attributes() { $attributes = parent::attributes(); // 添加自定义属性 $attributes[] = 'comment_count'; return $attributes; } // 模型其他代码... }
使用任意一种方法后,原来的查询代码不需要修改,就能直接通过$post->comment_count访问统计值,并且可以像示例中那样用于业务逻辑验证。
内容的提问来源于stack exchange,提问作者Dels
相关产品推荐
相关产品推荐

