通过BigDecimal步进或迭代

时间:2011-09-17 21:04:46

标签: ruby-on-rails increment loops bigdecimal

我的出发点基本上是瑞安贝特的RailsCast。我修改了他的代码以容纳OR子句以及AND。

在用户模型中,有几个名为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 个答案:

答案 0 :(得分:1)

您无法将范围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

来自fine manual

  

如果范围的起始对象支持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_lowprice_high是整数,您也不想使用IN,范围可能会扩展到相当大的列表,数据库必须单独比较每个