Ruby on rails 轨道运行总列
在完成了多个教程之后,我目前正在进行我的第一个rails项目 我正试图建立一个网页来跟踪我未来6个月的储蓄目标 基本上,该网站由一个表单输入组成,我在其中输入我将钱存入储蓄的日期和金额。然后,该站点更新一个折线图,以显示当前的节约与目标线的对比 到目前为止,我已经成功地构建了表单和数据库(使用postgresql),并创建了显示目标和接受表单输入的图表 我遇到的问题是,输入值显示为离散数字,而不是该月的累计总和(即第4周应为第1周到第4周的储蓄总和) 我最初考虑在数据库中有一个名为amount_cum的第三列,并在控制器的页面加载方法中放置一些行,这意味着数据库将在每次页面加载时重新计算,这可能会很慢 任何建议将不胜感激,我应该期待修改模型或控制器 相信明智的话Ruby on rails 轨道运行总列,ruby-on-rails,database,postgresql,cloud9-ide,Ruby On Rails,Database,Postgresql,Cloud9 Ide,在完成了多个教程之后,我目前正在进行我的第一个rails项目 我正试图建立一个网页来跟踪我未来6个月的储蓄目标 基本上,该网站由一个表单输入组成,我在其中输入我将钱存入储蓄的日期和金额。然后,该站点更新一个折线图,以显示当前的节约与目标线的对比 到目前为止,我已经成功地构建了表单和数据库(使用postgresql),并创建了显示目标和接受表单输入的图表 我遇到的问题是,输入值显示为离散数字,而不是该月的累计总和(即第4周应为第1周到第4周的储蓄总和) 我最初考虑在数据库中有一个名为amount_
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 PagesControllerweeks\u year))
如果@pages.save
flash[:success]=“已成功上载储蓄”
将\重定向到根\路径
其他的
flash[:danger]=@pages.errors.full_messages.join(“,”)
将\重定向到根\路径
结束
结束
私有的
def pages_参数
参数要求(:页数)。允许(:周,:金额)
结束
结束
和模型文件:
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) }] %>
<% 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) }]
%>
应用程序的屏幕截图,以便您可以看到如何根据目标显示图形。
在这种情况下,您可以在生成图表时在视图中使用
inject
:
<%= line_chart [
{name: "Amount Saved", data: @progress.group(:week).sum(:amount)},
{name: "Goal Savings", data: @goal.group(:week).sum(:amount) }] %>
<% 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) }]
%>
编辑2:
我认为inject
不应该修改原始的@progress数组(如果你是这么要求的),但是为了便于讨论(和诊断),请尝试以下方法(如果可以的话,我们当然可以改进):
在Rails中有一种更简单的计算总和的方法-您不必使用inject
,只需调用记录数组即可。在您的情况下,它将类似于:
@progress.sum(:amount)
然而,我在第一次阅读时解释你的问题的方式,我认为,你试图从一个实际和的数组中创建一个部分和的数组。我不知道这对你是否有用,但不管怎样,下面是我将如何使用Ruby的each\u 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
金额=[100200150300120]
部分_和=金额。每个_带有_对象([])。带有_索引do |(u,obj),i|
obj[100300450750870]
#示例:
部分_和[0]=100#第一和-仅第一个元素
部分和[2]=450第三部分和
部分_和[-1]=870#数组中所有金额的总和
希望您觉得这很有用。如果您能发布一些代码片段,可能会更容易提供帮助-对我来说很简单:Pso您需要按月累计金额?在这个阶段,我使用周作为我的x轴,因此我将日期转换为一年中的周。在我的头脑中,我希望控制器对数据库中的所有条目执行一个星期值小于当前对象的总和,然后将该数字保存到数据库中,或者有一个第三列,即运行总数。无论哪一个更容易实现,只要尝试一下——在循环中使用line_chart函数,它就会为每次迭代生成一个新的图形(我的页面上现在有大约50个图形)。还有一种方法可以通过自定义SQL来实现这一点(select
ing running total column),但我不确定它是否更清晰或更高效。我明白了。试试最新的版本。很抱歉,电池几乎没电了,没有充电器,很快就完成了,但应该是要点。但无担保;-)考虑到我们现在只是生成一个新的数据数组来提供给图表,将这段代码的大部分移动到模型中或者一个助手中可能更有意义。明天我拿到充电器后再看一看;-)这可以和散列一起使用吗?很抱歉不知道,但是您将如何修改它以应用于键值对,因为我仍然需要每个累积和都有一个:周的键,这样我就可以在折线图中绘制这两个键
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