現在、アプリに投票システムが実装されており、このコードを表示して、投票数で投稿を並べ替えています。
<%= render @posts.sort_by { |post| post.votes.count }.reverse %>
各投稿の投票数で並べ替えたいのですが、投稿が5日以上経過していないようにします。投票数と日付の両方で同時に投稿を並べ替えるにはどうすればよいですか。
現在、アプリに投票システムが実装されており、このコードを表示して、投票数で投稿を並べ替えています。
<%= render @posts.sort_by { |post| post.votes.count }.reverse %>
各投稿の投票数で並べ替えたいのですが、投稿が5日以上経過していないようにします。投票数と日付の両方で同時に投稿を並べ替えるにはどうすればよいですか。
これは間違っています。すべての並べ替え操作はデータベース側で行う必要があります。この例では、複雑なクエリを作成するためにArelを使用するか、カウンターキャッシュ列を作成することを検討してください。
投稿モデルに次のようなスコープを追加するだけです。
scope :five_days_ago, lambda { where("created_at >= :date", :date => 5.days.ago) }
次に、renderメソッドを次のように調整します。
<%= render @posts.five_days_ago.sort_by { |post| post.votes.count }.reverse %>
これは、使用している構造を維持したいことを前提としています。明らかに、他の提案のように、データベースですべてを実行することが最善の行動です。
luacassusは正しいです。少なくとも2つの理由から、ソートをデータベースに委任することをお勧めします。
カウンターキャッシュはおそらく最良のアイデアですが、複雑なクエリについては、試してみましょう。投稿モデルの場合:
class << self
def votes_descending
select('posts.*, count(votes.id) as vote_count').joins('LEFT OUTER JOIN votes on votes.post_id = posts.id').group_by('posts.id').order('votes_count desc')
end
def since(date)
where('created_at >= ?', date)
end
end
それで...
@posts = Post.votes_descending.since(5.days.ago)
確かに、dbにソートを行わせる方が良いでしょう。私は次のようなことをします
class Post < ActiveRecord::Base
default_scope :order => 'created_at DESC'
end
そうすれば、あなたは常にあなたの投稿をソートするでしょう、そして私が間違っていなければ、最後のものがあなたが最初に得るべきです、それはあなたの「逆」呼び出しの代わりになります。次に、上記のスコープを使用して、5日前の投稿のみを取得できます。また、データベースのcreated_at列にインデックスがあることを確認してください。あなたはこれを行うことができます
SHOW INDEX FROM posts
dbは、rubyよりもはるかに高速にこれを実行します。
私はそれを行う別の方法を考え出しましたが、あなたの助けに感謝しますが、それは最もきれいな方法ではないかもしれませんが、私はしました
def most
range = "created_at #{(7.days.ago.utc...Time.now.utc).to_s(:db)}"
@posts = Post.all(:conditions => range)
@title = "All Posts"
@vote = Vote.new(params[:vote])
respond_to do |format|
format.html
format.json { render :json => @users }
end
end
私のコントローラーのために
/ most:to =>'posts#most'のルートを作成しました
自分のビューにあった元のコードでビューを作成しました。
私はそれが最善の方法ではないことを知っていますが、私はまだコーディングに慣れていないので、その方法を理解するための最良の方法です。