My starting point is basically Ryan Bate's RailsCast. I have modified his code to accomodate OR clauses as well as AND.
In the User model there are a couple of attributes named hour_price_high and hour_price_low. Users will set their hourly rate range such as $45.25/h to $55.50/h. Site visitors will search for registered users in a price range such as $50.00/h to $60.00/h. This search should return all overlapping users. The respective migration entries for these attributes are:
# CreateUser migration
...
t.decimal "hour_price_high", :precision => 6, :scale => 2
t.decimal "hour_price_low", :precision => 6, :scale => 2
...
They are of type BigDecimal and I need to increment through these to search for users:
# 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
When I run this code, I get this error:
TypeError:
can't iterate from BigDecimal
Any ideas of how to increment through these? I only need to increment back two decimal places. Thanks for looking!
You can't convert a Range of BigDecimal to an array:
> 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
From the fine manual:
You can only iterate if the start object of the range supports the succ method
And BigDecimal doesn't have a succ
method. When you feed this:
["users.hour_price_low IN (?)", price_low..price_high]
to ActiveRecord as a condition, it probably sees that you've given it a Range and calls to_a
on it to get something that can be SQL-ified and that's where your error comes from.
I think you want to say this:
[ "users.hour_price_low >= :lo AND users.hour_price_low <= :hi", { :lo => price_low, :hi => price_hi } ]
Similar issues apply to your hour_price_high
.
Even if price_low
and price_high
were integers you wouldn't want to use IN
, the range could expand to a rather large list and the database would have to compare each one individually.