Home > Enterprise >  Ruby- date manipulation to fetch data
Ruby- date manipulation to fetch data

Time:12-22

I have a requirement in ruby where I want to fetch all the data present in database for the current month. However, there is a catch. I wanted to fetch the data of current month based on plan start data.

Ex:
 1. My plan is started on 5th Oct 2022.
 2. Let say, today's date is 3rd Dec 2022. I would want to fetch records from 5th Nov to 3rd Dec.
 3. Let say, today's date is 15th Dec 2022. I would like to fetch records of current cycle that is from 5th Dec till today.

There could be many cases, but the idea is I want to fetch the current month records based on the cycle start date for current month.

Since I am new to ruby, can someone please suggest me how to do it using DateTime or any relevant methods. Any help would be appreciated.

model:

class Customer
  include Mongoid::Document
  include Mongoid::Timestamps
  include SimpleEnum::Mongoid

  field :topic, type: String # This field is to store title/topic
  field :external_uuid, type: String # This represents unique ID
  field :start_time, type: DateTime
  field :duration, type: Integer
  field :created_at, type: DateTime 

  field :random, type: Float, default: -> { rand.round(8) }

  as_enum :type,
          internal: 'internal',
          external: 'external' 
end

CodePudding user response:

Based on my understanding that the plan starts on each 5th and you want to have the time-span from plan_start to NOW, you can get the start date with something along the lines of

require 'date'

plan_start_day = 5
today = DateTime.now.to_date
puts "Today is #{today}"
puts "Today is day #{today.day} of the month, plan starts on #{plan_start_day}."

start =
    if today.day < plan_start_day 
         DateTime.new(today.year,today.month - 1,plan_start_day)
    else 
         DateTime.new(today.year,today.month,plan_start_day)
    end
puts "Applicable plan start is #{start.to_date}"

For today we get an output like

Today is 2022-12-13
Today is day 13 of the month, plan starts on 5.
Applicable plan start is 2022-12-05

Now, assuming that the date you are looking for is in start_time column, that is of type DateTime, you can just query:

Customer.where('start_time > ? AND start_time < ?', start, today.end_of_day)

Of course created_at would also work, given that this column provides the information needed... Availability of end_of_day depends on Rails version but a manual increase as above should be easy enough...

If you want to have the number of items only use

Customer.where('start_time > ? AND start_time < ?', start, today.end_of_day).count

Now, I'd add this to the Customer model class as a static method

def self.monthly_sum(date)
    month = (date.day < Customer::PLAN_START_DAY) : date.month - 1 ? date.month 
    plan_start = DateTime.new(date.year, month, Customer::PLAN_START_DAY)
    plan_end = DateTime.new(date.year, month 1, Customer::PLAN_START_DAY)
    Customer.where('start_time > ? AND start_time < ?', plan_start, plan_end).count
end

This method uses the assumption that there are no "future" events, thus it would fetch the full month for any date. If the plan_month has already ended, it will get the full data. If it is the current plan_month, we get all data until today (as no newer entries exist).

The Customer::PLAN_START_DAY here is a constant. If the plan start is individual (per user, type, project, ...), you need to get it from the appropriate record and extract the day with the #day method presented above.

you can now do

Customer.monthly_sum(DateTime.now)

or what ever date is applicable and get the number of records matched.

  • Related