Ruby on Rails 变量在视图中显示 Active Record 数据而不是整数
Posted
技术标签:
【中文标题】Ruby on Rails 变量在视图中显示 Active Record 数据而不是整数【英文标题】:Ruby on Rails variable presenting Active Record data instead of integer in view 【发布时间】:2021-08-31 01:50:39 【问题描述】:我希望帮助器中有两个值是根据 Active Record 数据计算的,它们显示在同一个视图中,“gross_income_upload”和“all_time_gross”。 总收入还可以,但没有显示所有时间的总整数,而是显示的是 Active Record 数组数据。
有一个辅助函数和一个 .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
上传的总收入还可以,“gross_income_upload”为“R$20.0”,在视图中呈现良好。
Gross income uploaded: R$20.0
另一个值“all_time_gross”不合适。
预期的结果是循环内的计算,'all_time_gross' 是由 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 Pizza\n", 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 Shop\n", 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 Emporium\n", 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 Emporium\n", created_at: "2021-08-30 03:11:58.696714000 +0000", updated_at: "2021-08-30 03:11:58.696714000 +0000">]
【问题讨论】:
【参考方案1】: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
【讨论】:
非常感谢@rmlockerd !!以上是关于Ruby on Rails 变量在视图中显示 Active Record 数据而不是整数的主要内容,如果未能解决你的问题,请参考以下文章