【问题标题】:Rails: How To Deal With Many Subsets of Data From One Model?Rails:如何处理来自一个模型的多个数据子集?
【发布时间】:2012-01-19 16:08:55
【问题描述】:

Rails 3.0.3 应用程序(卡在 Dreamhost 共享服务器上)。

我有一个页面显示从一个模型的数据子集计算的平均值。

现在,每个平均值都是单独计算的,如下所示:

从视图上看,我使用 Devise 身份验证提供的 current_user 帮助器来调用位于用户模型中的平均方法,如下所示:

<%= current_user.seven_day_weight_average %>
<%= current_user.fourteen_day_weight_average %>
<%= current_user.thirty_day_weight_average %>

这是用户模型中的公共方法和平均方法:

def seven_day_weight_average
 calculate_average_weight(7)
end

def fourteen_day_weight_average
 calculate_average_weight(14)
end

def thirty_day_weight_average
 calculate_average_weight(30)
end

. . .
private
def calculate_average_weight(number_days)
  temp_weight = 0
  weights_array = self.weights.find_all_by_entry_date(number_days.days.ago..Date.today)
  unless weights_array.count.zero?
    weights_array.each do |weight|
      temp_weight += weight.converted_weight
    end
    return (temp_weight/weights_array.count).round(1).to_s
  else
    return '0.0'
  end
end

这似乎不是很有效 - 查询数据库以获取每个计算的平均值。

如何通过一个数据库查询计算这些平均值并将其提供给页面?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3


    【解决方案1】:

    您可以缓存过去 30 天的转换权重数组(假设 30 天是过去的最大天数),如下所示:

    def calculate_average_weight(number_days)
      @converted_weights ||= weights.where("entry_date > ?", 30.days.ago).group_by(&:entry_date).sort_by do |date,weights|
        date
      end.collect do |date,weights|
        weights.collect(&:converted_weight)
      end
      weights_during_period = @converted_weights[0..number_days-1].flatten
      weights_during_period.sum / weights_during_period.length
    end
    

    解释:

    首先,||= 获取或设置@converted_weights(即不要费心设置它,除非它是 nil 或 false)。这确保只有一个分贝命中。接下来,我们找到 30 天前的所有权重并按日期分组。这将返回一个 [date, weights] 数组,我们按日期对其进行排序。然后我们收集每个日期的转换权重,因此我们最终得到:[weights on day 1], [weights on day 2], ...

    现在,计算:我们将数组中跨越天数的值存储在weights_during_period 中。我们将值展平并计算平均值。

    【讨论】:

    • 感谢您的回复。不知道我应该用@converted_weights 做什么。我可以看到它包含 convert_weight 值,但它返回 nil 到调用 XXX_day_weight_average 调用。我的 Ruby 知识非常有限 - @converted_weights[-number_days..-1].sum 应该返回平均值吗?
    • @jacoulter 见上文 - 我已经简化并更正了代码,并添加了一些解释。
    • 感谢您花时间解释这一点。我让它工作了,但是每次调用该方法时我仍然会访问数据库(这是意料之中的。)有没有办法调用所需的范围,然后加载调用网页可用的实例变量?
    • 它只会在从同一个实例(在同一个请求周期)调用时缓存数据库命中。您可以发布调用该方法的上下文吗?
    • 请查看我对原始帖子的修改。我通过 Devise 身份验证 gem 提供的 current_user 助手从视图中调用方法。控制器是空的 - 我用 GET 调用视图。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多