I am doing an ActiveRecord find against the database, bringing back a
number of objects that have a created_on date between two dates.
After this fetch, I want to check if the result contains an object with
a specific date (actually I want to iterate through all days in a range,
and if the result contains a record, I want to get that record out of
the result array and interrogate it).
I know how to do this by doing a new ActiveRecord find for each date in
my iteration range, but I don’t want to do that as the overhead of so
many calls is too high. ]
So I need to keep my one hit on the database, but then query the result,
something like:
all_results = Item.where(— created in my date range —)
(start_date…end_date).each do |current_date|
if all_results.contains(:created_on => current_date)
… do something
else
do something else
end
end
My ActiveRecord is very poor - created_on is a field on the Item model,
but I can’t find out how to efficiently query an ActiveRecord result in
this way.
I know how to do this by doing a new ActiveRecord find for each date in
else
do something else
end
end
I don’t understand, why not just use start_date and end_date as the
range for your Item.where( ) call, then all the items returned will
have been created in that range, do you can iterate through them all
and do your ‘…do something’ action
My approach is this way because I can’t guarantee that there will be a
record with a certain date, yet I want to produce an array of results
for a full contiguous range of dates. In the case that there isn’t a
record with a certain date, I still want to put in a ‘placeholder value’
for that date in the array I’m creating.
Please quote the previous message so individual messages in the thread
make sense.
My approach is this way because I can’t guarantee that there will be a
record with a certain date, yet I want to produce an array of results
for a full contiguous range of dates. In the case that there isn’t a
record with a certain date, I still want to put in a ‘placeholder value’
for that date in the array I’m creating.
OK, I misunderstood. Going back to your original question then, you
say:
I know how to do this by doing a new ActiveRecord find for each date in
my iteration range, but I don’t want to do that as the overhead of so
many calls is too high.
Please quote the previous message so individual messages in the thread
make sense.
Sure, sorry.
My approach is this way because I can’t guarantee that there will be a
record with a certain date, yet I want to produce an array of results
for a full contiguous range of dates. In the case that there isn’t a
record with a certain date, I still want to put in a ‘placeholder value’
for that date in the array I’m creating.
OK, I misunderstood. Going back to your original question then, you
say:
I know how to do this by doing a new ActiveRecord find for each date in
my iteration range, but I don’t want to do that as the overhead of so
many calls is too high.
How do you know that the overhead is too high?
I’ve tried this approach, where I request each date in a range
individually, iterating over the range of dates I require. But the dates
may span 30-60 days or even more, and this causes ~60 separate sql
requests on the database. The result is a noticeable pause when loading
the page (backed up by benchmark figures), and a solution which doesn’t
scale to larger ranges of dates.
I am doing an ActiveRecord find against the database, bringing back a
number of objects that have a created_on date between two dates.
After this fetch, I want to check if the result contains an object with
a specific date
You could use Enumerable::group_by to collect-up your records by date,
and see if the resultant collection includes the date in question (and
if not, add it if you need to)
all_results = Item.where(— created in my date range —)
grouped_all_results = all_results.group_by{|result|
result.created_at.strftime(“%Y%d%m”)}
if grouped_all_results.include?(current_time.strftime(“%Y%d%m”))
… do something
else
do something else
end
You might make your group_by date and your lookup date by some other
method (like “date_value.to_s” or something), but as long as they end
up in the right format, it should work…