Search code examples
ruby-on-railsrubydatesidekiq

Sidekiq to perform action for last month and end of current month


I have this logic into my head but find it difficult to put into code; I can but not sure when to perform this action with Sidekiq

Compare last month's expenses with this month's expenses (end of this calendar month)

Worker Class:

def perform(*args) # params left out for this example
  [...]
  last_month = user.expenses.where(date: 1.month.ago) # ie Jan
  this_month = user.expenses.where(date: Date.today.at_beginning_of_month..Date.today.end_of_month) # ie Feb (end of Feb)

  # Then my if else here
end

Controller:

CompareExpenseWorker.perform_in(...)

I am stuck there. When should this perform? In 1 or 2 months?

I feel my mind is playing games on me. If I perform in 1 month, I will only get last month but not the current month ( full calendar month). If performed in 2 months, I feel that's not correct. Is it?


Solution

  • In the first place, the calculation for the last_month should be:

    # last_month = user.expenses.where(date: 1.month.ago) # incorrect
    last_month = user.expenses.where(
      date: 1.month.ago.beginning_of_month..1.month.ago.end_of_month)
    

    I believe, the whole logic should be changed, though. If you want to compare two full months, it should be done as:

    month_2 = user.expenses.where( # e.g. Feb
      date: 2.month.ago.beginning_of_month..2.month.ago.end_of_month)
    month_1 = user.expenses.where( # e.g. Mar
      date: 1.month.ago.beginning_of_month..1.month.ago.end_of_month)
    # run at any day in April, to compare two full months
    # user_id is the id of the user to build reports for
    CompareExpenseWorker.perform(user_id)
    

    Furthermore, I don’t think the call to CompareExpenseWorker should be put into controller, use cronjob for that, scheduled at 1st of every month.