我有一个简单的高尔夫应用程序,每个玩家都有:total_score
和:current_place
属性。我希望Rails根据该玩家的:current_place
是高于还是低于其他玩家来定义每个玩家的:total_score
属性。
换句话说,如果有两个玩家,一个有:total_score => 5
而另一个有:total_score => 4
我想让Rails成为第一个玩家:current_place => 1
,另一个玩家:current_place => 2
玩家的:current_place
,依此类推。我基本上希望它根据:total_score
列的下降来定义{{1}}值。
答案 0 :(得分: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块中,并在每次更新玩家总分时使其过期