2

我有一个简单的高尔夫应用程序,对于我拥有的每个球员:total_score:current_place属性。我希望 Rails 根据:current_place每个玩家的属性:total_score是高于还是低于其他玩家来定义每个玩家的属性。

换句话说,如果有两个玩家,一个有 a:total_score => 5另一个有:total_score => 4我希望 Rails 制作第一个玩家的:current_place => 1,另一个玩家的:current_place => 2,依此类推。我基本上希望它:current_place根据列的降序定义值:total_score

4

1 回答 1

0

您可以通过观察者来实现,当保存播放器时启动和 sql 查询,然后更新属性(使用 update_attribute 所以它不会触发回调)。但这将不是一个非常高效的解决方案,并且也可能存在竞争条件问题。

另一种解决方案是在某个地方实现相同的查询,并使模型的 current_place 函数访问结果。这也很容易缓存

代码:

class Player < ActiveRecord::Base
  def current_place
    self.class.current_place(self.id) if self.id
  end

  def self.all_places
    rank = {}
    pos = 0
    self.order_by('total_score desc').each{|p| rank[p.id] = (pos += 1)}
    rank
  end

  def self.current_place(id)
    all_places[id]
  end
end

我没有测试它,但我想这样的东西应该可以工作。要获得缓存部分,您只需将 all_places 包装在 Rails.cache.fetch 块中,并在每次更新玩家总分时将其过期

于 2012-07-11T00:43:42.283 回答