Шаг или перебор BigDecimal - PullRequest
       10

Шаг или перебор BigDecimal

1 голос
/ 18 сентября 2011

Моя отправная точка в основном RailsCast Райана Бэйта . Я изменил его код так, чтобы он соответствовал условиям OR и AND.

В модели User есть пара атрибутов с именами hour_price_high и hour_price_low. Пользователи будут устанавливать свой диапазон почасовой ставки, например, от $ 45,25 / ч до $ 55,50 / ч. Посетители сайта будут искать зарегистрированных пользователей в ценовом диапазоне, например, от 50 до 60 долларов в час. Этот поиск должен возвращать всех перекрывающихся пользователей. Соответствующие записи миграции для этих атрибутов:

# CreateUser migration
...
t.decimal "hour_price_high", :precision => 6, :scale => 2
t.decimal "hour_price_low",  :precision => 6, :scale => 2
...

Они имеют тип BigDecimal, и мне нужно увеличивать их для поиска пользователей:

# Search.rb
def low_price_or_conditions
    ["users.hour_price_low IN (?)", price_low..price_high] unless price.blank?
end
def high_price_or_conditions
    ["users.hour_price_high IN (?)", price_low..price_high] unless price.blank?
end

Когда я запускаю этот код, я получаю эту ошибку:

TypeError:
can't iterate from BigDecimal

Любые идеи о том, как увеличить через них? Мне нужно только увеличить назад на два знака после запятой. Спасибо за внимание!

1 Ответ

1 голос
/ 18 сентября 2011

Вы не можете преобразовать диапазон BigDecimal в массив:

> a = BigDecimal.new('1')
 => #<BigDecimal:12a082bb0,'0.1E1',9(18)> 
> b = BigDecimal.new('5')
 => #<BigDecimal:12a076ec8,'0.5E1',9(18)> 
> (a..b).to_a
TypeError: can't iterate from BigDecimal

Из тонкой инструкции :

Вы можете выполнять итерации, только если начальный объект диапазона поддерживает метод succ

А у BigDecimal нет метода succ.Когда вы передаете это:

["users.hour_price_low IN (?)", price_low..price_high]

в ActiveRecord в качестве условия, он, вероятно, видит, что вы дали ему Range, и вызывает to_a для него что-то, что может быть SQL-ified, и вот гдеваша ошибка исходит от

Я думаю, вы хотите сказать следующее:

[ "users.hour_price_low >= :lo AND users.hour_price_low <= :hi", { :lo => price_low, :hi => price_hi } ]

Подобные проблемы относятся к вашим hour_price_high.

Даже если price_low и price_high были целыми числами, которые вы не хотели бы использовать IN, диапазон мог бы расшириться до довольно большого списка, и базе данных пришлось бы сравнивать каждое из них по отдельности.

...