在视图中显示活动记录数据而不是整数的Ruby on Rails变量



我期望从同一视图中显示的活动记录数据计算的助手中的两个值,'gross_income_upload'和'all_time_gross'。总收入是可以的,但是没有显示总收入整数,而是显示活动记录数组数据。

有一个helper函数和一个.erb视图,代码如下:

应用程序帮助器(application_helper.rb):

module ApplicationHelper
def gross_income_upload
if Sale.any?
gross_income_upload = Sale.last.purchase_count*Sale.last.item_price
else
gross_income_upload = 0
end
end
def all_time_gross
if Sale.any?
all_time_gross = 0
sales = Sale.all
sales.each do |sale|
all_time_gross = all_time_gross + sale.purchase_count*sale.item_price
end
else
all_time_gross = 0
end
end
end

用户信息视图(_user_info.html.erb):

<h1>Gross income uploaded: R$<%= gross_income_upload %></h1>
<h2>All time gross: R$<%= all_time_gross %></h2>

变量'gross_income_upload'中的最后总收入是最后一次销售的收入,在函数中按以下方式计算:

gross_income_upload = Sale.last.purchase_count*Sale.last.item_price

上传的总收入是OK的,'gross_income_upload'是'R$20.0',它在视图中被很好地呈现。

Gross income uploaded: R$20.0

不合适的是另一个值'all_time_gross'。

期望的结果是循环内的计算,'all_time_gross'是由database中每个条目的sale purchase_count乘以item_price的总和来测量的:

sales.each do |sale|
all_time_gross = all_time_gross + sale.purchase_count*sale.item_price

视图中的值是Active Record数组数据,而不是整数:

All time gross: R$[#<Sale id: 1, purchaser_name: "João Silva", item_description: "R$10 off R$20 of food", item_price: 10.0, purchase_count: 2, merchant_address: "987 Fake St", merchant_name: "Bob's Pizzan", created_at: "2021-08-30 03:11:57.639361000 +0000", updated_at: "2021-08-30 03:11:57.639361000 +0000">, #<Sale id: 2, purchaser_name: "Amy Pond", item_description: "R$30 of awesome for R$10", item_price: 10.0, purchase_count: 5, merchant_address: "456 Unreal Rd", merchant_name: "Tom's Awesome Shopn", created_at: "2021-08-30 03:11:58.496490000 +0000", updated_at: "2021-08-30 03:11:58.496490000 +0000">, #<Sale id: 3, purchaser_name: "Marty McFly", item_description: "R$20 Sneakers for R$5", item_price: 5.0, purchase_count: 1, merchant_address: "123 Fake St", merchant_name: "Sneaker Store Emporiumn", created_at: "2021-08-30 03:11:58.593304000 +0000", updated_at: "2021-08-30 03:11:58.593304000 +0000">, #<Sale id: 4, purchaser_name: "Snake Plissken", item_description: "R$20 Sneakers for R$5", item_price: 5.0, purchase_count: 4, merchant_address: "123 Fake St", merchant_name: "Sneaker Store Emporiumn", created_at: "2021-08-30 03:11:58.696714000 +0000", updated_at: "2021-08-30 03:11:58.696714000 +0000">]

Ruby隐式返回方法中最后一个操作的结果。在all_time_gross中,当有Sale对象时,您设置了一个变量,但实际上并不返回它。该执行路径中的最后一个操作是sales.each,它(当给定一个块时)在迭代后返回枚举集/范围:

def all_time_gross
if Sale.any?
...
# The result of this is *not* all_time_gross
sales.each do |sale|
all_time_gross = all_time_gross + sale.purchase_count*sale.item_price
end
else
...
end
end

这就是为什么你结束了你的Sale对象的数组。在一个非常简单的层面上,你的问题的解决方案是确保all_time_gross是你的方法中的最后一件事:

def all_time_gross
if Sale.any?
all_time_gross = 0
sales = Sale.all
sales.each do |sale|
all_time_gross = all_time_gross + sale.purchase_count*sale.item_price
end
else
all_time_gross = 0
end
all_time_gross # ensures value returned
end

然而,您的方法(实际上两者都是)可以大大简化,从而减少了此类错误潜入的可能性。在all_time_gross的情况下,可以使用.sum方法来处理计算:

def all_time_gross
# Just bail out if there's nothing to do
return 0 unless Sale.any?
# Prefer .find_each over .all.each because it batches queries
Sale.find_each.sum { |sale| sale.purchase_count * sale.item_price } 
end

gross_income_upload中,您也不需要为变量赋值,因为您只是立即返回结果。相反,你可以这样做:

def gross_income_upload
return 0 unless Sale.any?
# In your version, calling Sale.last twice causes two queries
# for the same object
sale = Sale.last
sale.purchase_count * sale.item_price
end

最新更新