Rails 运行 总栏目
Rails running total column
在完成多个教程后,我目前正在处理我的第一个 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
在这种情况下,您可以在生成图表时在视图中使用 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) }]
%>
您没有 post 有关 Goal
模型的任何信息,但如果您还想绘制每周目标的增量增长图,则可以使用类似的技术。
编辑:
如果你需要一个数组数组,你可以尝试这样的事情(原谅我,我在我的 phone 上这样做)
<% @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) }]
%>
在 Rails 中有一种更简单的计算总和的方法 - 您不必使用 inject
,只需对记录数组调用 sum
。在你的情况下,它会是这样的:
@progress.sum(:amount)
但是,根据我在第一次阅读时解释您的问题的方式,我认为您是在尝试从一组实际和中创建一个部分和数组。我不知道这对你是否有用,但无论如何,我将使用 Ruby 的 each_with_object
和 with_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
希望你觉得有用。
在完成多个教程后,我目前正在处理我的第一个 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
在这种情况下,您可以在生成图表时在视图中使用 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) }]
%>
您没有 post 有关 Goal
模型的任何信息,但如果您还想绘制每周目标的增量增长图,则可以使用类似的技术。
编辑: 如果你需要一个数组数组,你可以尝试这样的事情(原谅我,我在我的 phone 上这样做)
<% @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) }]
%>
在 Rails 中有一种更简单的计算总和的方法 - 您不必使用 inject
,只需对记录数组调用 sum
。在你的情况下,它会是这样的:
@progress.sum(:amount)
但是,根据我在第一次阅读时解释您的问题的方式,我认为您是在尝试从一组实际和中创建一个部分和数组。我不知道这对你是否有用,但无论如何,我将使用 Ruby 的 each_with_object
和 with_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
希望你觉得有用。