Reputation: 13
The problem I'm trying to solve is to determine if a user has created a "tip" last month. This check will be done after the user creates a new tip.
I have an array of strings of past tip dates for the user called "tip_dates". My current solution using rails steps through each value in that array, converts it to a date, and checks to see if it is within the month.
Is this the most efficient solution? I'm concerned that as the date array gets larger this check may take a lot of time.
def tip_last_month
start_date = Date.today.beginning_of_month - 1.month
end_date = start_date.end_of_month
for tip_date in self.tip_dates do
if tip_date.to_date.between?(start_date, end_date)
return true
end
end
return false
end
Upvotes: 0
Views: 1318
Reputation: 578
Ruby people dont really use for
and explicit return
-s at the end of the functions. The value of the last expression will get returned by default.
What i do here is that i create an array by mapping the string to date objects and then passing them to an any?
block which will return true for the first match or return false if there is none.
def tip_last_month
start_date = Date.today.beginning_of_month - 1.month
end_date = start_date.end_of_month
tip_dates.map(&:to_date).any? do |date|
date.between?(start_date, end_date)
end
end
It is true that as the array gets larger, this function will slow down. You should consider storing the tips in the database in a separate table, by having one record for each tip and query them by date. It will be much faster that way.
You can read more about associations here:
http://guides.rubyonrails.org/association_basics.html
Upvotes: 1