Reputation: 7419
I need to do a bunch of queries.
In this case I think I query a result by many times,
Not completed in one query.
How to make my search results can be done by one query ?
q = WeatherLog.nearby(100, longitude, latitude)
if start_time and end_time
@weather_logs = q.where(datetime: start_time..end_time)
elsif start_time
@weather_logs = q.where("datetime > ?", start_time)
elsif end_time
@weather_logs = q.where("datetime < ?", end_time)
end
@weather_logs = @weather_logs.order(datetime: :asc).first(2000)
Upvotes: 0
Views: 121
Reputation: 2246
The first thing to realize is that ActiveRecord does not execute a query until it aboultely has to (lazy loading). While there are a number of lines of code building up the query, the query is only executed on methods like .all
, .each
, .first
etc. So from a performance standpoint your code is ok as your only executing one query to the database and not many.
However you can tweak the code to make it more human readable and maintainable:
class WeatherLog < ActiveRecord::Base
# ...
class << self
def between_times(times)
after_time(times[:start_time]).before_time(times[:end_time])
end
def after_time(time)
return self.all if time.nil?
where('datetime > ?', time)
end
def before_time(time)
return self.all if time.nil?
where('datetime < ?', time)
end
end
end
Using self.all
effectively skips the query condition while still enabling query chaining. This makes it possible to remove of all the if/else logic. Then you can chain the queries (or create a helper method within WeatherLog
):
WeatherLog.nearby(100, longitude, latitude).between_times(start_time: start_time, end_time: end_time)
Upvotes: 1