Rails select()和count()似乎不太好玩

时间:2014-04-29 08:01:08

标签: sql ruby-on-rails activerecord ruby-on-rails-4 ruby-on-rails-4.1

我注意到Rails(4.1)ActiveRecord有些奇怪,其中selectcount有时混合不好:

User.all.count
 => 103
User.all.size
 => 103
User.all.length
 => 103

到目前为止,这么好。我可以选择id

User.select(:id).all.count
 => 103
User.select(:id).all.size
 => 103
User.select(:id).all.length
 => 103

仍然很好。我也可以选择email

User.select(:email).all.count
 => 103
User.select(:email).all.size
 => 103
User.select(:email).all.length
 => 103

但现在问题开始了。当我选择 idemail

User.select(:id, :email).all.count
 (0.4ms)  SELECT COUNT(id, email) FROM `users`
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' email) FROM `users`' at line 1: SELECT COUNT(id, email) FROM `users`
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' email) FROM `users`' at line 1: SELECT COUNT(id, email) FROM `users`

User.select(:id, :email).all.size
 (0.4ms)  SELECT COUNT(id, email) FROM `users`
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' email) FROM `users`' at line 1: SELECT COUNT(id, email) FROM `users`
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' email) FROM `users`' at line 1: SELECT COUNT(id, email) FROM `users`

User.select(:id, :email).all.length
 => 103

为什么countsize(在这种情况下为count的别名)抛出异常,并且只有当我选择多个属性?

对此有解释吗?我觉得这很意外。

3 个答案:

答案 0 :(得分:9)

这是Rails 4.1中的一个错误。见https://github.com/rails/rails/issues/13648

答案 1 :(得分:1)

当您使用select并且参数有多个列时,您需要将其放在一个字符串中,格式如下:

User.select("id, email")

换句话说,列列表只能以pure string格式

传递

答案 2 :(得分:0)

感谢@camomileCase给您的提示。

对于我来说,我已经解决了此问题,方法是添加带有count选项的:all,并且有时根据需要添加另外的count。这种方式最适合我:

@grid = myscope.select(:thickness, :width, :length, "SUM(quantity_available) as quantity_available").group(:thickness, :width, :length)

@grid.assets.limit(nil).count(:all)
@grid.assets.limit(nil).count(:all).count