我有一个rails应用程序,其中包含以下许多代码:
Our active community of <%= Account.find_all_by_admin(false).count %>
我的问题是这是对观点进行统计的正确方法吗?看起来如此“肮脏”是否有更多的铁路,做点算的方法?我可能正在考虑命名范围,但我只是想确保这些类型的事情不会对性能产生更大的影响。
谢谢,
答案 0 :(得分:9)
您不需要名称范围来执行计数。
Account.where(:admin => false).count
但命名范围是使代码更具可重用性的绝佳方法。
命名范围对您的应用程序没有任何明显的性能影响。
答案 1 :(得分:6)
我建议你避免在我的模板中直接访问数据库,因为在缓存时你会失去一些灵活性。
尝试准备您需要在操作中呈现的所有数据,然后使用有意义的实例变量,例如@number_of_accounts
或@accounts.count
。
这将使您的视图更清晰,更容易调试,如果您以不同的格式(html,json等)渲染动作,也会更加干燥
至于你如何得到你的数字 - 这并不重要,只需从find_ *方法转向范围界定并编写可读代码
答案 2 :(得分:2)
命名范围不应对性能产生影响
scope :not_admin, where(:admin => false)
然后你可以拥有Account.not_admin.count
根据DGM的评论编辑:要在控制台中检查生成的SQL,请将Account.not_admin.to_sql
与Account.find_all_by_admin(false).to_sql
进行比较
答案 3 :(得分:2)
在rails 3中,一个简单的计数调用会发出一个简单的计数请求:
Contact.count
解析为:
SELECT COUNT(*) AS count_id FROM "contacts"
按字段名称查找全部将解析为:
Contact.find_all_by_country("Canada")
SELECT "contacts".* FROM "contacts" WHERE ("contacts"."country" = 'Canada')
我建议将管理列索引以便更快地查找,这可以转换为命名范围,但这本身只会预定义查询,而不是优化它。
重要的是要注意,如果你发出
Contact.find_all_by_country("Canada").count
count
是数组类的一个方法,实际上并没有对数据库发出计数:
Contact.find_all_by_country("Canada").count
SELECT "contacts".* FROM "contacts" WHERE ("contacts"."country" = 'Canada')
答案 4 :(得分:0)
您可以使用以下查询代替Account.where(:admin => false).count
Account.select(:id).where(:admin => false).count
只需选择一列,而不是全选。它生成以下查询,并且比前一个查询更快:
SELECT COUNT("accounts"."id") FROM "accounts" where admin = false
答案 5 :(得分:0)
您应该在控制器中创建一个instance variable
并在视图中使用它。
这将使您的视图清晰。
@accounts_count = Account.where(admin: false).count
并在`<%= @accounts_count%>
之类的视图中使用它如果要遍历结果和计数,可以使用以下方式:
@accounts = Account.where(admin: false)
在视图中,如下所示:
<%= @accounts.count %>
// For looping account
<% @accounts.each do |account| %>
# do some stuff
<% end %>
但是上面的方法将触发2个查询,其中1个用于计数,而另一个用于循环。
正确方法
使用size
代替count
。它将触发1个查询,但您需要更改视图中的计数顺序,例如:
// For looping account
<% @accounts.each do |account| %>
# do some stuff
<% end %>
<%= @accounts.size %>
如果您想要相同的顺序,则首先像下面那样加载用户对象
<%= @accounts.load.size %>
// For looping account
<% @accounts.each do |account| %>
# do some stuff
<% end %>