2016-08-04 11 views
0

から最も気に入っニュースの取得2つのモデルがあります。クエリはlikesの数をlikes equals falseからtrueと等しくする必要があります。最も高い数字は最も好きなニュースです。は、クエリ

@count_true_likes = Like.where('likes.like = ?', true).group(:news_id).count 
@count_false_likes = Like.where('likes.like = ?', false).group(:news_id).count 

結果はidを持つハッシュあると同類をカウント:私が試した何 。私はどのようにネガティブな好きな人からクエリーの好きな好きを差し引いて、すべてのニュースについてそれをするのか分からない。

+0

使用しているDBMSは何? MySQl/Postgresql? –

+0

@ArupRakshit Postgresql –

+0

この 'Like.group(:news_id、:like).select(:news_id、:like、COUNT(like))'を作成し、それをINNERクエリとして使用して実結果。 –

答えて

1

私は私の問題を解決:

@most_liked_news_id = Like.group(:news_id) 
          .select('news_id, SUM(case when likes.like then 1 else -1 end) as max_positive') 
          .order('max_positive desc').map(&:news_id).first 
@most_liked_news = News.find(@most_liked_news_id) 
2

このようなクエリは、データセットの増加に伴い非常に遅くなります。一般的な回避策は、upv​​otesとdownvotesの数をキャッシュすることです。 vote_resultがキャッシュされupvotes_count - downvotes_countある例えば

# Table name: news 
# 
# id   :integer   not null, primary key 
# title  :string   not null 
# content :text    not null 
# scope  :string   not null 
# created_at :datetime   not null 
# updated_at :datetime   not null 
# person_id :integer   not null 
# 
# upvotes_count :integer  not null 
# downvotes_count :integer  not null 
# vote_result  :integer  not null 

は、単に

News.order(vote_result: :desc).limit(10) # top 10 articles 

を行う欠点は、あなたがそれらのキャッシュされたカウンタ(あなたが投票を登録するときのものを対応して増加/減少)を維持する必要があることを、もちろん、です。

+0

@SergioTuelentsevあなたの提案をありがとうございますが、テーブルに余分な列を追加したくありません。 –

+1

@ŁukaszKorol:ああ、心配はありません。あなたはすぐに欲しいよ:) –