Sort by virtual attribute in Rails 3

BACKGROUND: I have a set of messages that you can vote on. I would like to sort the messages by their "vote rating", which is determined by the following equation:

((@ post.votes.count) / ((Time.now - @ post.created_at) ** 1))

I am currently defining a vote rating as such:

  def vote_score(x)
   ( (x.votes.count) / ( (Time.now - x.created_at) ** 1 ) )
  end

And sorting them as such:

@posts = @posts.sort! { |a,b| vote_score((b) <=> vote_score((a) }

PURPOSE: This method requires a huge investment of application loading time. Is there a better, more efficient way to do this sorting?

+3
source share
2 answers

If you use MySQL, you can do everything using a query:

SELECT   posts.id,
         (COUNT(votes.id)/(TIME_TO_SEC(NOW()) - TIME_TO_SEC(posts.created_at))) as score
FROM     posts INNER JOIN votes ON votes.post_id = posts.id
GROUP BY posts.id
ORDER BY score DESC

Or:

class Post
  scope :with_score, select('posts.*')
    .select('(COUNT(votes.id)/(TIME_TO_SEC(NOW()) - TIME_TO_SEC(posts.created_at))) as score')
    .joins(:votes)
    .group('posts.id')
    .order('score DESC')
end

What would you do the whole request:

@posts = Post.with_score.all

P.S: Post, SQL- , . , , :

class Post
  def score
    @score ||= self[:score] || (votes.count/(Time.now.utc - x.created_at.utc)
  end
end

P.S: SQLLite3:

strftime('%s','now') - strftime('%s',posts.created_at)
+14
  • sort!, ( ), :

    @posts.sort!{|a, b| vote_score(b) <=> vote_score(a) }
    
  • , , , , , , counter_cache , , . , db posts.

http://guides.rubyonrails.org/association_basics.html

0

All Articles