Rails where statement with datetime.month - ruby-on-rails

I am trying to find the data points within a database (PG) whose date is within a certain month (and would also quite like to check the year is the same also)
I have tried:
my_data.where("date.month = ?", month )
where 'month' is an integer (eg from Time.new.month) but doesn't seem to work...

So the query will be like this:
my_data.where("EXTRACT(MONTH FROM date) = ?", month)

Related

How can I use only the month and day of Date.today in Rails?

I want to display recent and upcoming anniversaries. Since dates are stored with year, the following code displays an empty array because none of my folks were married this year:
ann=Anniversary.where(anniversary: Date.today-7..Date.today+7)
So, how can I remove the year delimiter?
You can utilize the SQL EXTRACT method for this like below:
anniversaries = Anniversary.where('EXTRACT(month from anniversary) = ? AND EXTRACT(day from anniversary) IN (?)', Date.today.month, Date.today.day..(Date.today.day + 7))

How to run Rails queries over multiple date ranges (weeks)

I'm trying to iterate over each week in the calendar year and run a query.
range = Date.new(2020,3,16)..Date.new(2020,3,22)
u = User.where(created_at: range).count
But I'd like to do this for EACH week in another range (say since the beginning of this year).
Ruby's Date has a cweek function that gives you the week number but there doesn't seem to be a way to easily get from the week number to the date range.
Anyway, not sure how helpful cweek will be as I need week to run Sunday -> Saturday.
Thoughts?
I'm assuming this is Postgres and the model name is User based on your previous question.
If this blog is to to believed you can shift a date one day to get sun-sat day week.
User.group("(date_trunc('week', created_at::date + 1)::date - 1)")
.count
If you want the to select the actual week number while you are at it you can select raw data from the database instead of using ActiveRecord::Calculations#count which is pretty limited.
class User
# #return [ActiveRecord::Result]
# the raw query results with the columns count, year, week
def self.count_by_biblical_week
connection.select_all(
select(
"count(*) as count",
"date_part('year', created_at)::integer as year",
"(date_part('week', created_at::date + 1) - 1)::integer as week"
).group(:week, :year)
)
end
end
Usage:
results = User.where(created_at: Date.new(2020,3,16)..Date.new(2020,3,22))
.count_by_biblical_week
results.each do |row|
puts [row[:year], row[:week], row[:count]].join(' | ')
end
Adding the year to the group avoids ambiguity if the results span multiple years.

Rails where based on association

I'm trying to query items based on an association but getting a bit confused with how to phrase the date part of my query. The dates are stored in text format like "2018-12-25".
year = params[:ridden_in]
#items = Item.joins(:cycle).where(cycles: { (:date.to_date).year: year })
Anyone able to help out where i'm going wrong?
The easiest way to do this is to use SQL functions. You could try to hide the SQL behind AREL but that very quickly becomes an incomprehensible mess.
One way would be straight string manipulation:
Item.joins(:cycle).where('substring(cycles."date" from 1 for 4) = ?', year)
or slightly more future-proof since your date will eventually become a real date:
Item.joins(:cycle).where('extract(year from cycles."date"::date) = ?', year)
Item.joins(:cycle).where('extract(year from cast(cycles."date" as date)) = ?', year)
Both of those assume that your date columns really do follow the ISO8601 date format.
If you're doing this a lot then you could add a partial index on cycles.date (i.e. index the result of whichever function you end up using).

Rails 5 active record query where date range overlaps with other date range

I have a model with planting_date_begin and planting_date_end. I want to retrieve all records where any date in planting_date_begin..planting_date_end overlap with the range for the current_week
example:
if planting_date_begin: 3/5/2017 and planting_date_end: 3-12/2017
and this week is 3/26/2017-4/1/2017 it is not included in query.
if planting_date_begin: 3/1/2017 and planting_date_end: 4/15/2017 it would be included.
I set current_week range:
today = Date.today
days_in_week = today.at_beginning_of_week..today.at_end_of_week
This syntax is not right but I want to do something like:
Planting.where((planting_date_begin..planting_date_end).overlaps?(days_in_week) )
What is a succinct way to handle this? Incidentally, I am using postgres in case there is a way to do it differently.
Maybe not as succinct, but I have to do this a lot in a current project and my method is...
start_date = Date.today.at_beginning_of_week
end_date = Date.today.at_end_of_week
#plantings = Planting.where('planting_date_end >= ? AND planting_date_begin <= ?', start_date, end_date)
This covers all overlaps.. if planting starts before the range and ends after the range, if planting starts during the range, if planting ends during the range.

Comparing datetime and date in a .where() on Rails

I'm working on an event system where admins can select events to feature and add promotional text. As they need to add additional text the featured events are in their own table and reference the event details.
I'm now trying to output featured events for each day in the next week. Simplified example:
day = DateTime.now.to_date
featured_events = #featured_events.where('event.start_datetime = ?', day)
The problem is that start_datetime is in datetime format and day is in date format so it always outputs nothing. Is it possible to compare these two values with .where()?
Thanks!
May be you're looking for this:
#featured_events.where('event.start_datetime > ? and event.start_datetime < ?', DateTime.now, 1.day.from_now.beginning_of_day)
You don't say what database you're using.
In PostgreSQL we'd truncate the datetime inside the DB query so the DBM can do the compare. On MySQL we'd use a function to convert the datetime to a date.

Resources