2014-06-13 258 views
0

用戶have_many帖子。用戶has_many帖子。獲得至少有1個帖子的所有用戶

在一個視圖中,我想獲取至少有1個帖子的所有用戶的按字母順序排列的列表。這是我目前如何做到的。有沒有辦法讓所有這一行/使用更好的Rails的ActiveRecord約定?

@users.order("name ASC").each do |user| 
    if user.posts > 0 
    ... 
    end 
end 
+0

你可以看看這個並相應地修改它:http://stackoverflow.com/questions/4314987/find-all-posts-with-more-than-a-defined-number-of-comments –

回答

0

我們可以使用這個獲得至少有一個帖子的所有用戶ID。

Post.uniq.pluck(:user_id); 

然後我們可以按如下方式獲取所有用戶。

User.order(:name).find(Post.uniq.pluck(:user_id)); 
+1

This生成兩個數據庫調用。問題中的代碼只有一個,所以在性能方面我會說這是一個比這更好的選擇 –

3

您目前的解決方案並不差(這是一個單一的查詢),但它可以改進。

您可以使用ActiveRecord的內置計數器緩存功能來存儲父級關聯對象的數量(在這種情況下是與用戶關聯的帖子數量)。然後,你可以通過精心設計這樣的查詢:

User.where('posts_count > 0').order('name ASC') 

這裏是:counter_cache的文檔(taken from here):

:counter_cache

緩存通過對關聯類屬於對象的數量使用increment_counter和decrement_counter。計數器緩存在該類的一個對象被創建時遞增,並在其被銷燬時遞減。這要求在關聯類(例如Post類)上使用名爲#{table_name} _count的列(例如,用於所屬類Comment類的comments_count) - 即在關聯者上創建#{table_name} _count的遷移類(例如Post.comments_count將返回緩存的計數,請參閱下面的註釋)。您還可以通過爲該選項提供列名而不是真/假值來指定自定義計數器高速緩存列(例如,counter_cache :: my_custom_counter)。注意:指定計數器高速緩存將使用計數器高速緩存將其添加到該模型的只讀屬性列表中attr_readonly。

0

User.joins(:posts).order('users.name asc')將執行內部連接,如文檔here中所述。計數器緩存也不是一個不好的解決方案。

+0

如果您計劃在同一個操作中使用與用戶關聯的帖子,那麼使用聯接是一個好主意。 –

+0

嗯,不,如果你想實際檢索帖子,你需要'includes'。如果你想在後面的範圍鏈中過濾與帖子有關的帖子,或者如果你想過濾它們的存在,'joins'就很有用。 – histocrat

相關問題