Reputation: 8119
Working from the rails console, why is the following find_by
returning nil?
2.0.0 (main):0 > Location.last
Location Load (0.8ms) SELECT "locations".* FROM "locations" ORDER BY "locations"."id" DESC LIMIT 1
=> #<Location id: 92, district: nil, address: "8026 S KEDZIE AVE", city: "CHICAGO", state: "IL", zip: 60652, website: nil, location: nil, latitude: 41.7474748619454, longitude: -87.7023800625442, location_type: "fire_station">
2.0.0 (main):0 > lat = Location.last.latitude
Location Load (0.8ms) SELECT "locations".* FROM "locations" ORDER BY "locations"."id" DESC LIMIT 1
=> 41.7474748619454
2.0.0 (main):0 > Location.find_by( latitude: lat)
Location Load (0.8ms) SELECT "locations".* FROM "locations" WHERE "locations"."latitude" = 41.7474748619454 LIMIT 1
=> nil
I originally thought it something to do with Sqlite so I switched over to Postgres but still yield the same result. Someone else working on the some project ran the same find_by
yielded the proper result. What is going on with my system that this is happening?
Upvotes: 1
Views: 65
Reputation: 1392
As a quick workaround, you could use SQL ROUND
method
Location.find_by("ROUND(latitude, 3) = ?", "%.3f" % lat)
but it'll effectively kill your index on the locations table (assuming you have one) and not really suitable for large amounts of data.
Upvotes: 0
Reputation: 29379
Assuming this is a problem with Float
equality check, here are some suggestions from http://www.mail-archive.com/[email protected]/msg02703.html:
Given: x = 11.967 y = 11.966999999999 <-- loss of precision due to hex<->decimal conversion
Compare based on a range (as suggested in a prior post) 11.9670 <= x < 11.968.
Compare string representations of the floating point values: x == y => false ("%.3f" % x) == ("%.3f" % y) => true
Store values using a fixed point data type (such as DECIMAL in MySQL): lng DECIMAL(5,3) x -> lng => 11.967 y -> lng => 11.967 <-- rounded based on the rules defined in the database Making it safe to compare equality on the two values
Store fixed decimal values as integers in the database and convert them when displaying them. I only mention this technique because it is an option for storing currency values. Rather than store dollars, store cents instead and convert to dollars with displaying the values on the view. $1.60 -> 160 (in the database)
Upvotes: 2