【问题标题】:Ruby on Rails - Counting goals of a team in many matchesRuby on Rails - 在多场比赛中计算球队的进球数
【发布时间】:2012-12-25 13:52:56
【问题描述】:

我有一个Match模型和一个Team模型。

我想计算一支球队在联赛中的进球数(因此我必须将该球队在 home_matchesaway_matches 中的所有得分相加)。

我该怎么做?我应该在 ma​​tchesteams 数据库表中添加哪些列?

【问题讨论】:

    标签: ruby-on-rails database associations counting rails-models


    【解决方案1】:

    我假设您的 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你想缓存这个值(只缓存我建议的实现最近更改的值,但根据需要进行调整)。

    【讨论】:

    • 非常感谢,我会尽快尝试的。但是,由于我是 Rails 新手,所以当您谈论将值缓存到模型中时,我想知道您的意思。我该怎么办?
    【解决方案2】:

    你不要把它放在任何桌子上。数据库有一条规则:永远不要在数据库中存储可以从其他字段计算的数据。

    您可以使用此函数轻松计算:

    def total_goals
      self.home_matches.collect(&:home_goals).inject(&:+)+self.away_matches.collect(&:away_goals).inject(&:+)
    end
    

    应该为你做。如果您想为联赛过滤数学,您可以使用scope

    【讨论】:

    • 关于该规则 - 保存信息这样不会每次都重新计算不是更好吗?
    • 我不同意不惜一切代价避免重复数据。缓存表和列非常有用。事实上,counter_cache 是内置在 ActiveRecord 中的(缓存列的一个例子,对这个特定问题没有直接用处)。
    • 是的,我真的不认为这符合数据库的规则,如果您想索引该数据怎么办?
    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多