2013-11-13 5 views
1

Работа с консолью рельсов, почему следующие find_by, возвращающий нуль?find_by не ведет себя так, как ожидалось

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 

Первоначально я думал, что это что-то делать с Sqlite, поэтому я перешел на Postgres, но по-прежнему дают тот же результат. Кто-то другой, работающий над каким-то проектом, побежал тем же самым find_by, что дало правильный результат. Что происходит с моей системой, что это происходит?

+1

вопросы округления, скорее всего. Поплавки, как известно, неточны. – sevenseacat

+0

@sevenseacat Как я могу получить к нему доступ точно? – rudolph9

+0

Что такое тип данных в вашей базе данных? –

ответ

2

Предполагая, что это проблема с проверкой Float равенства, вот несколько предложений от http://www.mail-archive.com/[email protected]/msg02703.html:

Дано: х = 11,967 у = 11,966999999999 < - потеря точности из-за гекс < -> десятичного преобразования

  1. Сравнить на основе диапазона (как это было предложено в предыдущем посте) 11,9670 < < = х 11,968.

  2. Сравнить строковые представления значений с плавающей точкой: х == у => ложный ("% .3f" % х) == ("% .3f" % г) => истинно

  3. значения магазина, используя тип данных с фиксированной точкой (например, DECIMAL в MySQL): LNG DECIMAL (5,3) х -> LNG => 11,967 у -> LNG => 11,967 < - округленное основанные на правилах, определенных в базе данных Обеспечение безопасности для сравнения равенства на tw o значения

  4. Сохранять фиксированные десятичные значения как целые числа в базе данных и конвертировать их при их отображении. Я упоминаю только этот метод, потому что это вариант для хранения значений валюты. Вместо того, чтобы хранить доллары, храните центов вместо этого и конвертируйте в доллары с отображением значений на экране . $ 1,60 -> 160 (в базе данных)

+0

Я закончил с _3._, Казалось, что самый простой способ решения проблемы. – rudolph9

0

Как быстро решить эту проблему, вы можете использовать SQL ROUND метод

Location.find_by("ROUND(latitude, 3) = ?", "%.3f" % lat) 

но это будет эффективно убить индекс в таблице местоположений (предполагается, что вы есть один) и не очень подходит для больших объемов данных.

Смежные вопросы