2

这是我的场景:

class User < ActiveRecord::Base
  has_many :things
  # attr_accessible :average_rating
end

class Thing < ActiveRecord::Base
  belongs_to :user 

  has_one :thing_rating
end

class ThingRating < ActiveRecord::Base
  belongs_to :thing

  attr_accessible :rating
end

我想在我的用户模型中有一个属性,该属性具有他相关 ThingsRating 的平均计算。

管理此问题的最佳做法是什么?

谢谢

4

2 回答 2

2

可能你可以使用不确定的关系,但你可以试试这个

class User < ActiveRecord::Base
  has_many :things
  has_many :thing_ratings, through: :things

  # attr_accessible :average_rating

  def avg_rating
    @avg_rating ||= thing_ratings.average("thing_ratings.rating")
  end 
end
于 2013-04-18T12:02:37.970 回答
1

简单的方法:

class User < ActiveRecord::Base
  has_many :things

  def avg_rating
    @avg_rating ||= average(things.map(&:thing_rating))
  end

  private
  def average(values)
    values.inject(0.0) { |sum, el| sum + el } / arr.size
  end
end

作为首发,这很好。但是,如果您有一点流量,您可能会发现自己遇到了扩展问题。

然后,您必须对其进行重构,以避免每次为不同的用户调用该方法时对事物进行 SQL 查询。
然后你可以有几个可能性:

  • 在您的用户数据库中添加一个字段,该字段avg_rating将在ThingRating创建或更新时更新。
  • 使用 memcached 或 redis 数据库来缓存值,并在每次ThingRating更新或创建 a 时使缓存失效。

当然,这些解决方案并不详尽。您可以找到其他更适合您需求的产品。

于 2013-04-18T11:54:37.157 回答