2017-04-21 7 views
2

컨트롤러에서이 코드를 사용하여 Heavy 분류의 모든 사용자에 대해 평균 paper_weight에 액세스하고 있습니다.ActiveRecord : 계산시 nil을 0으로 처리 하시겠습니까?

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 

이어서 가변 @heavy_indust_officepaper는 도면에 표시되어있다.

문제는 하나 이상의 사용자가 항목을 paper_type: 'Officepaper'에 넣었을 때 위의 코드가 평균값을 올바르게 계산하지 않는 것입니다.

나는 내가 그들의 industry_type: 'Heavy' 하나에 두 명의 사용자를 가지고 있기 때문에 소수 (30) 되고 다른 사용자가 paper_type: 'Officepaper'에서 nil 항목이 paper_type: 'Officepaper'의 하나 개의 항목을 가지고 있음을 알고있다. 나의 이해함으로써

계산은 30 + 0/2(users) = 15

다음 1545

를 제공해야하지만 그 대신 변수 @heavy_indust_officepaper보기에 90를 표시 ...을해야하는하는 3를 곱해야한다 30 * 3의 결과

위 코드에서 nil0으로 변환하는 방법이 있습니까 ???

제발 나 한테 조언 해 줄 수있어? 여기

내가 하루 일찍 물어 질문에 대한 링크입니다, 내가 (다른 사람의 사이에서) Using .average with .pluck in ruby on rails app?

+0

당신을했다 'nil.to_i'을 시도해보십시오. 'irb'에서 해보십시오 ...'.first.to_i * 3' ... 그냥 생각보다 ... – Myst

+0

로컬 변수를 사용하는 대신 동일한 쿼리를 두 번 실행하는 이유는 무엇입니까? – max

+0

안녕하세요, http://stackoverflow.com/questions/22220449/sql-avg-with-null-values가 도움이 될 수도 있습니다 – Bohdan

답변

3

문제는 여기에서이 코드에 도움이되었다하는 것은 pluck이 무엇을 당신의 오해입니다. 모든 사용자에 대해 평균 의 배열을 반환합니다. 귀하의 예제에서 당신에게

[30, nil] 

을 반환 그래서 당신이 90 ([30, nil].first * 30 =>90)을받을 이유입니다.

모든 사용자의 평균을 구하려면 average을 사용하십시오.


솔루션 :

당신은 평균 계산하는 동안 제로로 NULL 변환 COALESCE을 사용할 수 있습니다 알고 있어야

User.where(industry_type: 'Heavy') 
    .joins(:papers) 
    .where(papers: { paper_type: ['Officepaper', nil] }) 
    .average('COALESCE(papers.paper_weight, 0)') * 3 
#=> 15 

것은 그 COALESCE0 어떤 null 값을 변환 할 때 계산하는 동안 averagenil이 반환되는 경우 이 아니며 ca 계산 average.이 사건을 처리하는 것은 당신이 결정할 문제이지만, 이미 @max은 매우 간단 옵션 중 하나를 보여 주었다에

(쿼리 결과 위에 average 변수에 기록되어 있다고 가정) 방법 :

average.nil? ? 0 : average * 3 
+0

좋은 답변이지만 여전히 nil을 확인해야합니다. "지정된 열의 평균값을 계산합니다. 행이 없으면 nil을 반환합니다." http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-average – max

+0

@max 당신 말이 맞아요, 감사합니다! 수정 됨 –

1
avg = User.where(industry_type: 'Heavy') 
.joins(:papers) 
.where(papers: { paper_type: ['Officepaper', nil] }) 
.average('papers.paper_weight') 

@heavy_indust_officepaper = avg.nil? ? 0 : avg * 3 
+0

'avg?라고 말하는 것이 더 간결 할 것입니다. 평균 * 3 : 0'. – moveson

+0

@moveson'avg &. * 3'은 더 간결 합니다만, 부족함이 주요 포인트가 아니라고 생각합니다. –

+0

동의하지만, 삼항을하는 데 어려움을 겪으 려한다면, 추가 메서드 호출을 제거합니다. ''nil? '이라고 평가하는 변수의 본질적인 허위성에 의존하는 것보다 분명히 더 나은 결과를 이끌어 내지 않으면'# nil?'을 사용하지 않으려 고합니다. – moveson