ruby-on-rails - rails 3 : Sort a ActiveRelation by Ratings Counted from another table

标签 ruby-on-rails ruby-on-rails-3 postgresql activerecord sqlite

我的评分系统很简单,用户喜欢或不喜欢这篇文章。

基本上,我有这样的东西,而且效果很好:

class Article
  has_many :ratings
  def self.by_ratings
    all.sort_by{|article| (article.ratings.where(like: true).size).to_f / (article.ratings.size) }
  end
end

如您所料,我们的应用在数据库中变得庞大,流量增加,这部分代码成为瓶颈。

我正在尝试用纯 sql 重写它以提高性能。我还试图将其作为 ActiveRelation 与其他条件链接起来。也尝试编写 sql 但没有成功。有什么想法吗?

谢谢!

使用:

  • rails 3.0.10
  • 事件记录
  • Sqlite 3(我们可以切换到 Postgresql)

最佳答案

您需要的是缓存列。

1) 创建迁移以访问缓存列:

class AddRatingCacheToArticles < ActiveRecord::Migration

  def self.up
    add_column :articles, :rating_cache, :decimal, :default => 0.0
  end

  def self.down
    remove_column :articles, :rating_cache
  end

end

2) 在 Article 中定义一个更新方法,它将进行计数:

class Article < ActiveRecord::Base
  has_many :ratings

  def update_rating_cache
    current_rating = ratings.where(:like => true).count.to_f/ratings.count.to_f
    update_attribute(:rating_cache, current_rating)
  end
end

3) 在 Rating 中设置一个回调,以便在它们被保存时触发 update_rating_cache 方法:

class Rating < ActiveRecord::Base
  belongs_to :article

  after_save :update_article_rating_cache
  after_destroy :update_article_rating_cache

  def update_article_rating_cache
    article.update_rating_cache if article
  end
end

4) 现在可以非常轻松地按评分对文章进行排序:

class Article < ActiveRecord::Base
  has_many :ratings

  def self.by_ratings
    order('rating_cache DESC')
  end

  def update_rating_cache
    current_rating = ratings.where(:like => true).count.to_f/ratings.count.to_f
    update_attribute(:rating_cache, current_rating)
  end
end

这可以用作 ActiveRelation!

祝你好运:)

关于ruby-on-rails - rails 3 : Sort a ActiveRelation by Ratings Counted from another table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7242470/

相关文章:

ruby-on-rails - 无法启动 resque worker

ruby-on-rails - 在集成测试中模拟/ stub 是个好主意吗?

ruby-on-rails-3 - 如何将 Prawn PDF 文件存储到 Amazon S3 中

python - django.db.utils.ProgrammingError : relation "auth_user" does not exist

ruby-on-rails - 检查时间是否介于 ruby 的两倍之间

ruby-on-rails - Ruby Object#id 警告和 Active Record

ruby-on-rails - 如何根据参数动态访问实例变量[:controller]?

ruby-on-rails - Rails 3.1 路由——集合不工作

sql - 更新数字列,使其字段的值构建一个以 x 开头的序列

sql - 需要有关返回符合特定条件的最后记录的 SQL 查询的帮助