I have a table shift and it has a field expiry_date.
I have a requirement to get a list of all shifts with an expiry date in less than 20 days. How can I achieve this in rails?
I tried something like this but it is returning me all Shifts that have expiry_date 20 days ago but I need which will expire in less than 20 days.
scope :20_days_to_expire, -> { where('expiry_date < ?', 20.days.ago) }
Please help me fix this.
You can filter between today and 20 days later:
scope :20_days_to_expire, -> { where(expiry_date: Time.zone.now.beginning_of_day..(Time.zone.now.beginning_of_day + 20.days)) }
Related
In my Rails 5 app I want to send an alert 10 minutes after a certain datetime in my database. For example 10 minutes after the created_at datetime.
So I run a cronjob every 1 minute and have to look in my database for all records where created_at was 10 minutes ago.
My created_at field is in the format 2017-06-01 12:00:00. How can I get all records where created_at was 10 minutes ago?
My problem are the seconds and I can't simple do (this is not valid Ruby code, it's just to show my point):
where created_at == 10.minutes.ago
I would have to do something like
where created_at > 10.minutes.ago AND created_at < 9.minutes.ago
But this does not seem very clean. Are there better solutions?
You have to provide range in order to get records..however, to avoid dependencies with seconds, you can do something like below elegantly..
range = range = 10.minutes.ago.beginning_of_minute..10.minutes.ago.end_of_minute
records = YourModel.where(created_at: range)
I have an active relation Bar object with an attribute shift_date. shift_date represents each day between March and June. March and June comes from Foo which has attributes start_month and end_month:
f = Foo.find(1)
days = (f.end_month - f.start_month).to_i
weeks = (days * 0.142857).round(2)
f.bars will give me days objects. Where days is the total amount of objetcs.
My trouble is to get Bars objects, objects for week 1, 2 or 3 etc:
f.bars.where('shift_date >= ?', (weeks/7.days)).group_by{ |result| result }
operator does not exist: timestamp without time zone >= numeric
So what am I saying? Give me all objects on week 1 or week 5, if any. How do I go about this, please?
Im on to something but not right:
f.bars.where('shift_date >= ?', Date.today).group_by{ |result| result}
Edit:
Im almost there. I could splat out the days with:
days_array = *(f.start_month..f.end_month)
then
f.bars.where(shift_date: days_array[0]..days_array[7])
That would be the answer! But...not really. For my views, I need to group the splatted days in a 7 days interval as week, so days_array[0] to days_array[7] would be week 1 and days_array[8] to days_array[14] would be week 2 etc. How to show that in the view? This will give me everything I need.
Hi I have define this method
def change_date
date = Date.today
start_date = date.change(year: 2015, month: (2 * 3)).at_beginning_of_quarter
p 'aaaaaa'
p start_date
end
give me invalid date error .change is not working or am I doing it in a wrong way please guide me how to solve this. Thanx in advance.
This is because the month you are specifying doesn't have the current day.
I mean the current month (July) has 31 days but the month you're setting (June) has only 30 days. You can change your code like so:
# in Rails:
date = Date.today.beginning_of_month # or Date.today.change(day: 1)
Then chain your 'change' in front of the date variable.
This actually happens, because today is the 31 of July, and not all months have 31 days in it, for example June, the 6th month, has only 30 days in it.
In my Rails 4 app I receive a month and a year from the user which I would like to make into a date. The new date should be the 1st of the following month but I'm not sure on the best way to tackle this.
At the moment I have
expiry = Date.new(params[:expYear],params[:expMonth].to_i + 1,1)
but this isn't ideal because if someone entered 12 as the month my approach would make the month 13 which of course doesn't exist (and also the year wouldn't get updated either).
Are there any useful functions that could help here?
You can do this:
year,month = params[:expYear].to_i,params[:expMonth].to_i
Date.new(year,month) + 1.month
or use the end_of_month as #dax wrote:
Date.new(year,month).end_of_month + 1.day
That will resolve your problem
I think this would be more simple
expiry = Date.new(params[:expYear],params[:expMonth].to_i).next_month
I solved it using this - sorry just before your answer user2503775
expiry = Date.new(params[:expYear].to_i,params[:expMonth].to_i) + 1.month
Note You have to convert to integers before this can be done. I also found out that if the day param is left out it defaults to 1 anyway so that's handy
I would do something like
Date.new(params[:expYear].to_i,params[:expMonth].to_i,1).advance(months: 1)
Do something like
Time.zone.local(params[:expYear].to_i, params[:expMonth].to_i, 1, 0, 0, 0)
I have a number of products that are perishable. Therefore, each product has an attribute called hours_expiration that tells how many hours the product can be used before it goes bad.
For ex, apple expires in 168 hours; nut expires in 4320 hours.
Given, the product's hours-to-expiration and the current time (Time.now or Date.now), how can I humanize the time-to-expiration in some of the following sample ways?
Your item is set to expire in about:
6 months and 14 days
1 month and 13 days
1 month and 1 day
27 days
1 day
23 hours
1 hour
50 minutes
1 minute
Looking for something robust and simple!
The distance_of_time_in_words helper seems to be what you ask for.
Another easy helper is time_ago_in_words: https://apidock.com/rails/ActionView/Helpers/DateHelper/time_ago_in_words
The method name might sound like it can only deal with past dates but actually it handles future dates just fine. You can try it in your rails console:
expiration_date = Time.now + 5.days
puts "Expires in #{helper.time_ago_in_words(expiration_date)}"
"Expires in 5 days"
Look at Distance of time docs: http://apidock.com/rails/ActionView/Helpers/DateHelper/distance_of_time_in_words