Slo*_*boy 3 ruby activerecord ruby-on-rails ruby-on-rails-4 ruby-on-rails-5
paper_weight我在控制器中使用此代码来访问分类中所有用户的平均值Heavy。
if User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: 'Officepaper' } )
.pluck('avg(paper_weight)').first.nil?
@heavy_indust_officepaper == 0
else
@heavy_indust_officepaper = User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: 'Officepaper' } )
.pluck('avg(paper_weight)').first * 3
end
Run Code Online (Sandbox Code Playgroud)
然后该变量@heavy_indust_officepaper将显示在视图中。
nil问题在于,当一个或多个用户在 中输入条目时,上面的这段代码似乎无法正确计算平均值paper_type: 'Officepaper'。
我知道这一点是因为我有两个用户,其中industry_type: 'Heavy'
一个有一个条目,其中paper_type: 'Officepaper'的条目是十进制 30。另一个用户有nil条目paper_type: 'Officepaper'。
根据我的理解计算应该是30 + 0 / 2(users) = 15
然后15乘以3它应该给出45
但是变量@heavy_indust_officepaper显示90在视图中......这必须是以下结果30 * 3
有没有办法将上面代码中的 转换为 with nil???0
请有人给我建议吗?
这是我今天早些时候提出的问题的链接,我从中获得了有关此代码的帮助Using .average with .pluck in ruby on Rails app?
这里的问题(除其他外)是你对它的误解pluck。它会返回每个用户的平均某些内容的数组。所以在你的例子中它会返回你
[30, nil]
Run Code Online (Sandbox Code Playgroud)
这就是为什么你得到90( [30, nil].first * 30=> 90)。
要获得所有用户的平均值,请使用average。
解决方案:
您可以在计算平均值时使用COALESCE转换NULL为零:
User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: ['Officepaper', nil] } )
.average('COALESCE(papers.paper_weight, 0)') * 3
#=> 15
Run Code Online (Sandbox Code Playgroud)
需要注意的一件事是 while会在计算时COALESCE将任何null值转换为,如果没有要计算的记录,仍然会返回。0averagenilaverage
如何处理这种情况由您决定,但@max已经显示了非常简单的选项之一(假设上述查询结果写入average变量):
average.nil? ? 0 : average * 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2472 次 |
| 最近记录: |