我需要从Yii CActiveRecord派生类中获取第一条记录.在Rails中,我只能做到这一点:
post = Post.first
Run Code Online (Sandbox Code Playgroud)
我想我可以和Yii做同样的事情:
$post = Post::model()->first();
Run Code Online (Sandbox Code Playgroud)
但是这种方法不存在.我是否必须找到有条件才能获得第一张唱片?
我没有在CActiveRecord的文档中看到first()所以我假设答案是否定的,它没有第一个方法.那么如何才能查询第一条记录呢?
这可行,但肯定是一个丑陋的黑客.当然有更好的方法.
$first = Post::model()->findAll(array('order'=>id, 'limit'=>1));
Run Code Online (Sandbox Code Playgroud)
Yii不会对如何订购数据做出任何假设.良好的数据库设计要求如果使用代理键,该键应具有无意义的值.这意味着不要用它来订购.
抛开这个问题,这可能是进行查询的最佳方式:
$first = Post::model()->find(array('order'=>'id ASC'));
Run Code Online (Sandbox Code Playgroud)
通过使用find而不是findAll自动将LIMIT 1结果应用于您的结果.我不会跳过包含order by子句,因为这可以确保数据库将一致地排序结果.
如果您经常使用此查询,则可以创建以下方法.更新:修改它以在primaryKey为复合或缺失时抛出异常.我们也可以添加更多错误检查,但我们将其作为练习留给读者.;)
public function first($orderBy = null){
if(!$orderBy){
$orderBy = self::model()->tableSchema->primaryKey;
}
if(!is_string($orderBy)){
throw new CException('Order by statement must be a string.');
}
return self::model()->find(array('order'=>$orderBy));
}
Run Code Online (Sandbox Code Playgroud)
然后在扩展CActiveRecord的类中包含此方法,然后从该类扩展所有模型.
我写的包装器将默认按主键排序结果,但如果您愿意,您可以选择传递不同的列和方向(ASC OR DESC).
然后,如果您为post类执行此操作,则可以访问第一个模型,如下所示:
$first = Post::model()->first();
Run Code Online (Sandbox Code Playgroud)
CActiveRecord::find() 仅返回一个模型。
$first=Post::model()->find();
Run Code Online (Sandbox Code Playgroud)