2009-02-10 96 views
0

我想寫沒有成功的ActiveRecord查找查詢。請幫忙!Rails的ActiveRecord:計數協會的關聯

我的項目的這個功能是一種類似Digg的功能的博客:每個註冊用戶都可以爲博客文章本身或其任何回覆添加一顆明星。

因此,這裏有相關的模型類:

  • 博文(的has_many回覆)
  • 回覆(belongs_to的博客文章)
  • 主演(這代表一個用戶主演一個博客帖子或回覆的作用;它具有BlogPost和Reply的多態接口,在內部引用它們爲:starrables,充滿:starrable_id和:starrable_type字段)

所以,我是tr ying要做的是在blog_post.rb中寫一個方法,它將返回BlogPost對象及其所有Reply類的starrings總數。也就是說,如果博客文章有10顆星,並且它有兩個回覆,每個回覆都有5顆星,那麼它應該返回20.

如何在不進行數據庫交易的情況下編寫此查詢?

回答

2

我會建議用SQL來做。你可以通過幾種方式來完成。你使用MYSQL嗎?如果你想要做的與2個查詢,然後添加數字加在一起,你可以做這樣的事情在SQL:

select count(starrings.id) from starrings where starrable_type='BlogPost' and starrable_id=#{blogpost.id}

select count(starrings.id) from starrings join replies on starrings.starrable_type='Reply' and starrable_id=replies.id and replies.blog_post_id=#{blogpost.id}

注:我沒有測試這個SQL可能有拼寫錯誤或者輸入錯誤。

您可以使用'Starring.count_by_sql(您的sql在這裏)'運行SQL計數,然後將2個數字相加。你也許可以用一個聯合將它歸結爲1條SQL語句,但我不會打擾。

0

假設你有兩個博客帖子和回覆的多態方法stars,返回Starring對象的每個(您可能沒有,但它是有道理的,我認爲你應該)然後blog_post.rb你可以這樣做:

def total_number_of_stars 
    stars.size + replies.inject(0) { |s,v| s.stars.size += v.stars.size } 
end 

無可否認,這將在幕後做相當多的查詢,但這就是Rails的工作原理。如果性能不夠好,可以使用find_by_sql和定製的SQL。

+0

我現在基本上在做這個,但是它的擴展性非常差。假設有一種方法可以在一個或兩個查詢中完成此操作,我寧願讓數據庫完成繁重的工作。 雖然謝謝! – 2009-02-10 23:37:21