簡體   English   中英

在 Rails 中進行計數的正確方法是什么?

[英]What's the right way to do counts in Rails?

我有一個 Rails 應用程序,其中包含許多以下代碼:

Our active community of <%= Account.find_all_by_admin(false).count %>

我的問題是,這是對視圖進行計數的正確方法嗎? 看起來如此“骯臟”有沒有更荒謬的計數方法? 我可能在考慮命名范圍,但我只想確保這些類型的東西不會對性能產生更大的影響。

謝謝你,

您不需要名稱范圍來執行計數。

Account.where(:admin => false).count

但是命名范圍是使代碼更可重用的極好方法。

命名范圍對您的應用程序沒有任何明顯的性能影響。

我建議你避免在我的模板中直接訪問數據庫,因為那樣你會在緩存方面失去一些靈活性。

嘗試准備您需要在操作中呈現的所有數據,然后使用有意義的實例變量,例如@number_of_accounts@accounts.count

如果您以不同的格式(html、json 等)呈現動作,這將使您的視圖更清晰、更易於調試,並且也會更 DRY

至於你如何得到你的數字 - 它並不那么重要,只是從 find_* 方法轉向范圍和編寫可讀的代碼

在 rails 3 中,一個簡單的 count 調用會發出一個簡單的 count 請求:

Contact.count

被解析為:

SELECT COUNT(*) AS count_id FROM "contacts"

find all by field name 將解析為:

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')

命名范圍不應影響性能

scope :not_admin, where(:admin => false)

然后你可以有Account.not_admin.count

根據 DGM 的評論進行編輯:要在控制台中檢查生成的 SQL, Account.find_all_by_admin(false).to_sql Account.not_admin.to_sqlAccount.find_all_by_admin(false).to_sql進行比較

您可以使用以下查詢代替Account.where(:admin => false).count

Account.select(:id).where(:admin => false).count

只需選擇一列,而不是選擇全部。 它生成以下查詢,並且比前一個查詢更快:

SELECT COUNT("accounts"."id") FROM "accounts" where admin = false

您應該在控制器中創建一個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 %>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM