【发布时间】:2012-12-25 13:52:56
【问题描述】:
我有一个Match模型和一个Team模型。
我想计算一支球队在联赛中的进球数(因此我必须将该球队在 home_matches 和 away_matches 中的所有得分相加)。
我该怎么做?我应该在 matches 和 teams 数据库表中添加哪些列?
【问题讨论】:
标签: ruby-on-rails database associations counting rails-models
我有一个Match模型和一个Team模型。
我想计算一支球队在联赛中的进球数(因此我必须将该球队在 home_matches 和 away_matches 中的所有得分相加)。
我该怎么做?我应该在 matches 和 teams 数据库表中添加哪些列?
【问题讨论】:
标签: ruby-on-rails database associations counting rails-models
我假设您的 Match 模型看起来像这样:
belongs_to :home_team, class_name:"Team"
belongs_to :away_team, class_name:"Team"
attr_accessible :home_goal_count, :away_goal_count
如果是这样,您可以添加一个方法来提取目标数量:
def goal_count
home_matches.sum(:home_goal_count) + away_matches.sum(:away_goal_count)
end
由于这可能很昂贵(特别是如果您经常这样做),您可能只是将此值缓存到团队模型中并在Match 模型上使用after_save 挂钩(并且,如果匹配被删除,那么after_destroy 钩子):
after_save :update_team_goals
def update_team_goals
home_team.update_attribute(:goal_count_cache, home_team.goal_count)
away_team.update_attribute(:goal_count_cache, away_team.goal_count)
end
由于您想为联赛执行此操作,您可能希望在 Match 模型上添加一个 belongs_to :league,在 goal_count 方法(及其查询)中添加一个联赛参数,以及一个 goal_count_cache_league 列 if你想缓存这个值(只缓存我建议的实现最近更改的值,但根据需要进行调整)。
【讨论】:
你不要把它放在任何桌子上。数据库有一条规则:永远不要在数据库中存储可以从其他字段计算的数据。
您可以使用此函数轻松计算:
def total_goals
self.home_matches.collect(&:home_goals).inject(&:+)+self.away_matches.collect(&:away_goals).inject(&:+)
end
应该为你做。如果您想为联赛过滤数学,您可以使用scope。
【讨论】:
counter_cache 是内置在 ActiveRecord 中的(缓存列的一个例子,对这个特定问题没有直接用处)。