Rails运行总列

时间:2017-01-06 08:05:12

标签: ruby-on-rails database postgresql cloud9-ide

我目前正在完成我的第一个rails项目,经过多个教程。

我正在尝试建立一个网页来跟踪我未来6个月的储蓄目标。

本质上,该网站由一个表单输入组成,我在其中输入我将钱存入储蓄的日期和金额。然后,该站点会更新折线图,以显示当前的节省与目标线的比较。

到目前为止,我已经成功构建了表单和数据库(使用postgresql)并创建了显示目标并接受表单输入的图表。

我遇到的问题是输入值显示为离散数字,而不是当月的累计总和(即第4周应该是第1周到第4周的节省总和)。

我认为最初在数据库中有一个名为amount_cum的第3列,并在控制器的页面加载方法中添加了一些行,这意味着数据库会在每个页面加载时重新计算,这可能很慢...

如果我想修改模型或控制器,我们将不胜感激吗?

放在明智的话语上

class PagesController < ApplicationController
def home
 @pages = Pages.new
 @progress = Pages.order(:week)
 @goal = Goals.all
end

def create
 @pages = Pages.new(pages_params)
 weeks_year=Date.parse(params[:pages][:week]).strftime("%U")

 @pages = Pages.new(pages_params.merge(:week => weeks_year))


if @pages.save
  flash[:success]="Savings Uploaded Successfully"
   redirect_to root_path
else
   flash[:danger]=@pages.errors.full_messages.join(", ")
   redirect_to root_path
 end
 end  
private
 def pages_params
 params.require(:pages).permit(:week, :amount)
end

end

模型文件:

 class Pages < ActiveRecord::Base
  validates :week, presence: true
  validates :amount, presence: true
 end

我的视图文件 - 我使用chartkick gem生成图表:

  <%= line_chart [
  {name: "Amount Saved", data: @progress.group(:week).sum(:amount)},
  {name: "Goal Savings", data: @goal.group(:week).sum(:amount) }] %>

应用程序的屏幕截图,以便您可以看到图表如何针对目标显示。 link

2 个答案:

答案 0 :(得分:1)

在这种情况下,您可以在生成图表时在视图中使用inject

<% saved = [] %>
<% @progress.inject(0) do |sum, page| %>
<%   current = sum + page.amount
<%   saved << current %>
<%   current # the return value is passed in as `sum` in the next iteration %>
<% end %>
<%= line_chart [
      {name: "Amount Saved", data: saved},
      {name: "Goal Savings", data: @goal.group(:week).sum(:amount) }]
%>

更短但有点尴尬:

<% saved = [] %>
<% @progress.inject(0) { |sum, page| (saved << sum + page.amount).last} %>
<%= line_chart [
      {name: "Amount Saved", data: saved},
      {name: "Goal Savings", data: @goal.group(:week).sum(:amount) }]
%>

您没有在Goal模型上发布任何信息,但如果您还希望每周绘制目标的增量增量,则可以使用类似的技术。

编辑: 如果你需要一个数组阵列,你可以尝试这样的事情(原谅我,我在手机上这样做)

<% @progress.inject(0) { |sum, page| (saved << [page.week, sum + page.amount]).last.last} %>

编辑2: 我不认为inject应该修改原始的@progress数组(如果这就是你要问的那个),但是为了参数(和诊断),请尝试以下方法(如果是作品):

<% saved = [] %>
<% cum_sum = 0 %>

<% @progress.map do |page| %>
<%   cum_sum += page.amount %>
<%   saved << [page.week, cum_sum] %>
<% end %>
<%= line_chart [
      {name: "Amount Saved", data: saved},
      {name: "Goal Savings", data: @goal.group(:week).sum(:amount) }]
%>

答案 1 :(得分:0)

有一种更简单的方法来计算Rails中的总和 - 您不必使用inject,只需在记录数组上调用sum即可。在你的情况下,它将是这样的:

@progress.sum(:amount)

然而,我在第一次阅读时解释你的问题的方式,我想,你试图从一组实际总和中创建一个部分和的数组。我不知道这对你有用,但无论如何,这就是我使用Ruby each_with_objectwith_index以及Rails'sum的方式:

amounts = [100, 200, 150, 300, 120]

partial_sums = amounts.each_with_object([]).with_index do |(_, obj), i|
  obj << amounts[0..i].sum
end                      # => [100, 300, 450, 750, 870]

# Examples:
partial_sums[0]  = 100  # 1st sum - just the first element
partial_sums[2]  = 450  # 3rd partial sum
partial_sums[-1] = 870  # the total of all the amounts from the array

希望你觉得有用。