0

我必須在索引頁中呈現最新的14篇文章。 爲了避免用戶多次提醒帖子並阻止帖子創建者投票。減少rails的數據庫請求存在?方法

我這樣做是爲了不顯示給予好評鏈接(在視圖級):

if !(post.upvotes.exists?(:user_id => current_user.id) or post.user_id == current_user.id) 

但是,每次我重新加載索引頁時,它會發送這樣的請求14倍。

Upvote Exists (0.2ms) SELECT 1 AS one FROM "upvotes" WHERE "upvotes"."post_id" = $1 AND "upvotes"."user_id" = 2 LIMIT 1 [["post_id", 22]] 

我只是想知道,如果這是常見的,我真的想知道是否有更好的方法來達到同樣的效果,同時降低了數據庫查詢。

謝謝。

回答

1

你的問題我想是N + 1個查詢,看到這個鏈接Active Record eager_load

隨着熱切的加載,你可以有2個查詢DB,1個所有職位和1個所有相關upvotes。

現在你有1查詢所有職位,然後爲每個職位,你會得到1查詢所有upvotes爲特定職位。

例如

# in controller you do something like 
@posts = Post.condition 

# to add eager load do next 
@posts = Post.includes(:upvotes).condition # this will load all related upvotes for all posts 
# you don't have to eager load users, because you don't handle user object, 
# you are checking if user_id that is already loaded with upvotes object, 
# s matching current_user.id, you are not fetching user object from DB 
# --- 
# use this 
# this way you work with loaded data instead of making request to DB to check 
# if exsits upvotes with user_id == current_user.id 
if !(post.upvotes.map(&:user_id).include?(current_user.id) || post.user_id == current_user.id) 


# instead of 
if !(post.upvotes.exists?(:user_id => current_user.id) or post.user_id == current_user.id) 
# when you use method exists? rails will make new query to DB even if you eager load data 
+0

我改爲:@posts = Post.includes(:upvotes,:user).all.last(14).reverse,它仍然發送14個查詢。 – 2014-12-03 16:14:15

0

我不得不承認它的醜陋,但我希望它可以幫助:

@posts = Post.joins(:upvotes).where('upvotes.user_id = ?', current_user.id).group('posts.id').having('COUNT(upvotes.id) > 0') 

我已經嘗試了一些我的模型和它的工作。