0

I want to write an action where I can return one quote per day from DB. my db look like this

|id|quote|

so,if I call this action today it should return the same quote throughout the day but tomorrow it should return another quote from the db. I thought of mapping the quote ids to the today's date but not sure how to do it.

code_m
  • 35
  • 4
  • Welcome to SO. Your question isn't asked well. Please see "[ask]", "[Stack Overflow question checklist](https://meta.stackoverflow.com/questions/260648)" and all their linked pages. You gave us requirements, but don't show any effort toward solving the problem yourself, which tells us you want us to write the code for you, not help you fix the code you wrote, which is off-topic. – the Tin Man Jun 03 '20 at 21:31

1 Answers1

3

You can get consecutive quotes via:

Quote.order(:id).offset(0).first
Quote.order(:id).offset(1).first
Quote.order(:id).offset(2).first
# ...

To get a quote for the current day, you can utilize Date#jd which returns the date's Julian day:

Date.parse('2020-06-01').jd #=> 2459002
Date.parse('2020-06-02').jd #=> 2459003
Date.parse('2020-06-03').jd #=> 2459004

Since you (probably) don't have that many quotes, this value needs to be transformed into a value we can pass to offset, i.e. a value between 0 and the total number of quotes. This is where the modulo operator % can help – it returns just that, looping over at the end: (e.g. for 22 quotes)

Date.parse('2020-06-01').jd % 22 #=> 18
Date.parse('2020-06-02').jd % 22 #=> 19
Date.parse('2020-06-03').jd % 22 #=> 20
Date.parse('2020-06-04').jd % 22 #=> 21
Date.parse('2020-06-05').jd % 22 #=> 0
Date.parse('2020-06-06').jd % 22 #=> 1

Putting it all together:

require 'date'

def quote_of_the_day(date = Date.current)
  offset = date.jd % Quote.count
  Quote.order(:id).offset(offset).first
end

Note that this runs two queries: one to get the total number of quotes and another one to get the quote for the given date. You might want to cache the result.


Also note that adding new quotes might have unexpected results because the modulo operation would return a totally different offset:

Date.parse('2020-06-03').jd % 22 #=> 20

# after adding a new Quote

Date.parse('2020-06-03').jd % 23 #=> 5

You can compensate this by adjusting the jd result accordingly:

ADJUSTMENT = 15
(Date.parse('2020-06-03').jd + ADJUSTMENT) % 23 #=> 20
Stefan
  • 109,145
  • 14
  • 143
  • 218