Boolean values not being "read" in Rails

251 views Asked by At

I imported some values from Excel using Roo into boolean fields in my Rails app.

In Rails Console it looks like everything is working fine, but in my Rails App the boolean values don't seem to be read by Rails.

I have a DataPoint model. One attribute of DataPoint is the boolean field currently_employed.

In Rails Console it works like this (seems fine):

003:0 > x.currently_employed
=> true
004:0 > z.currently_employed
=> false
005:0 > x.currently_employed == false
=> false
006:0 > x.currently_employed == "true"
=> false
007:0 > x.currently_employed == true
=> true
008:0 > z.currently_employed == false
=> true
009:0 > z.currently_employed == "false" 
=> false
010:0 > z.currently_employed == true 
=> false

Given everything seems to look good in Console, I'd have thought that this formula in my data_point.rb model would work fine:

def self.pct_true(data_points)
    true_count = 0
    data_points.each do |x|
        if x.currently_employed
            true_count += 1
        else
        end
    end
    return true_count / data_points.count * 100
end

But it returns the value zero, even though I have multiple instances of DataPoint where x.currently_employed evaluates to true in Rails Console.

Interestingly, when I change the boolean field "currently_employed" to the integer field "annual_income", this same function counts each instance and returns the value 100.

Given the Rails Console results above, any idea what might be wrong with the method in my model?

Thanks!

3

There are 3 answers

0
Anthony On BEST ANSWER

Your issue is just in integer division - take a look:

[1] pry(main)> 1 / 100
=> 0
[2] pry(main)> 20 / 100
=> 0

A quick fix might be to do:

return true_count / data_points.count.to_f * 100
1
ConnorCMcKee On

You're dividing an integer by an integer, so you can't get a decimal value. Because you're dividing the true_count by the TOTAL count, that division will always result in 0 unless EVERY data_point.currently_employed is true. Thus your only possible results are 0 * 100 (0) or 1 * 100 (100), and 100 would be incredibly rare.

You could fix it like this:

return true_count.to_f / data_points.count.to_f * 100

This will turn your integers into floats (essentially decimals), and allow for division.

Unrelated Note

Your code:

if x.currently_employed
  true_count += 1
else
end

Could be refactored as:

true_count += 1 if x.currently_employed
0
floum On

As stated above, this is an integer division related issue

 Unrelated note as well :

true_count = data_points.select {|data_point| data_point.currently_employed }.size