Get all records created today in Rails - ruby-on-rails

I want to get all the records from the database which are create_at today. But when I do
Model.where('DATE(created_at) = ?',Date.today)
it returns only the last record that is created today. I have 3 records with created_at
2015-03-03 11:38:31
2015-03-03 11:59:00
2015-03-03 11:33:04
. But it returns only the record with '2015-03-03 11:38:31' this created_at date.
Also referred How to delete all records created today?, Getting all rows created today. I want to know why is this happening?
Also tried
Model.where("DATE(created_at) = ?",Date.today)
and
Tracking::TrackingLogin.where("created_at >= ?", Time.zone.now.beginning_of_day)
Please someone explain what is happening in my code?

Try the following:
Model.where("created_at >= ?", Time.zone.now.beginning_of_day)

Model.where("created_at >= ?", Time.zone.now.beginning_of_day)
Model = your model name
(i.e,. User.where("created_at >= ?", Time.zone.now.beginning_of_day))

Model.where("created_at >= ?", Date.today)

Related

How do you query a Model by parent ID & created at date

I'm trying to find all the records that have a specific channel_id, and were made less than 1 day ago. The query finds the records with the given channel_id but does not respect the date restriction. Instead, it returns records created at any date.
#discussions = Discussion.where('channel_id = ? and created_at > ?', current_user.subscription.pluck(:channel_id), 1.days.ago )
I expected to only get the Discussions that had relevant subscriptions channel_id, and were made less than 1 day ago. But instead, this query ignores the created at restriction but returns the Discussions that had the corresponding subscriptions channel ID.
#discussions = Discussion.where("channel_id IN (?) AND DATE(created_at) >= ?", current_user.subscription.pluck(:channel_id), (Date.today - 1.day))
OR
#discussions = Discussion.where("channel_id IN (?) AND created_at >= ?", current_user.subscription.pluck(:channel_id), (Date.today - 1.day).end_of_day)
Or
Discussion.where("DATE(created_at) >= ?", (Date.today - 1.day))
.where("channel_id IN (?)", current_user.subscription.pluck(:channel_id))
#discussions = Discussion.where("channel_id = :channel AND created_at > :date", channel: current_user.subscription.pluck(:channel_id), date: Date.yesterday )

Rails Date Query for setting Expiration

I'm creating a marketplace app where sellers can list items to sell. I want to set an expiry date so listings over 30 days old do not show on the site.
I found some similar examples online but can't get this query to work.
#listings = Listing.where('created_at <= ?', Date.created_at + 30.day)
You want to query items whose created_at time is >= the current date (Date.current) - 30 days (30.day). So the query should simply be:
#listings = Listing.where('created_at >= ?', Date.current - 30.day)
You can also replace Date.current with Time.now or DateTime.now.
UPDATE: as user3334690 mentioned in a comment, it's recommended that you make this a model method since it's something that should be in the Model layer:
# app/models/listing.rb
def self.not_expired
where('created_at >= ?', Date.current - 30.day)
end
# now in controllers you can do something like
#listings = Listing.not_expired

Rails 4: Method that only shows records in the next 24 hours

I have a model called Reminders with a column called Start (datetime).
How do I only show records where Start occurs in the next 24 hours. I tried something like this:
#user_reminders = user.reminders.where(["start >= ?", DateTime.now] && ["start <= ?", 1.day.from_now])
But it's returning incorrect results.
Users have many Reminders. Reminders belong to Users. All the associations are working fine, it's just returning results that are not within the date range. This is in a mailer if changes anything.
Cheers
This might help explain what is going on
[1] pry(main)> [1] && [2]
=> [2]
So when you do
.where(["start >= ?", DateTime.now] && ["start <= ?", 1.day.from_now])
you end up doing
.where(["start <= ?", 1.day.from_now])
which might explain your issues.
Try
.where("start >= ?", DateTime.now).where("start <= ?", 1.day.from_now)
This works as you might want.
That's the wrong syntax for chaining two where conditions together. The && is evaluated immediately, resolves to the second operand, and only that gets passed through to where.
Any of these will work:
.where('start >= ?', DateTime.now).where('start <= ?', 1.day.from_now)
or
.where('start >= ? and start <= ?', DateTime.now, 1.day.from_now)
or, probably the best option,
.where(start: DateTime.now..1.day.from_now)
you should do
#user_reminders = user.reminders.where(start: DateTime.now..1.day.from_now)

Ambiguous table reference

This problem seems fairly simple, but I've never encountered one like this.
Here are the settings:
Post has_many :reader_links
Post has_many :readers, :through => :reader_links
I need to find out if there are readers reading a post.
#post.reader_links.where('created_at >= ?', 45.minutes.ago).any?
Works great.
#post.readers.where('created_at >= ?', 45.minutes.ago),any?
throws an ambiguous table column error because it's confused whether the created_at column means that of reader object or reader_link object. This happens because the class of a reader is actually User. How do I query readers who were created by reader_links 45 minutes ago?
I'm looking for something like..
#post.readers.where('reader_link.created_at >= ?', 45.minutes.ago)
If I get it right, you just need to specify which created_at column you're talking about:
#post.readers.where('reader_links.created_at >= ?', 45.minutes.ago).any?
You coul merge the scopes to get rid of ambigious errors, so each scope has it's own visibility range.
using meta_where:
Post.scoped & (ReaderLink.scoped & User.where(:created_at.gt => 45.minutes.ago))
without meta_where:
Post.scoped.merge(ReaderLink.scoped.merge(User.where('created_at >= ?', 45.minutes.ago))
This will result in arrays of Post objects containing the reader_links and readers data for all readers younger than 45 minutes. Please try it in the rails console.
Edit: for a single post
post_with_fresh_users = Post.where('id = ?', some_id).merge(ReaderLink.scoped.merge(User.where('created_at >= ?', 45.minutes.ago))
Edit: all fresh readers of a post (different order)
fresh_readers_for_post = User.where('created_at >= ?', 45.minutes.ago).merge(ReaderLink.scoped.merge(Post.where('id = ?', #post.id))
How it works:
http://benhoskin.gs/2012/07/04/arel-merge-a-hidden-gem

Use active record to find a record by month and day, ignoring year and time

I have a model (Entries) with five years worth of records (one record per day). I need a method that, when passed a date object such as 2011-12-25 00:00:00, will show me ALL the records that have happened on 12/25 (querying against the :created_at column), regardless of the year or time that's passed.
RoR 3.0.9 / Ruby 1.9.2p290
You can use the MONTH and DAY values of mysql. Maybe something like:
Model.where("MONTH(created_at) = ? and DAY(created_at) = ?", somedate.month, somedate.day)
A general solution that should work with most SQL databases (include MySQL and PostgreSQL):
Entry.where('extract(month from created_at) = ? AND extract(day from created_at) = ?', d.month, d.day)
SQLite doesn't understand extract though so you'd have to use:
Entry.where("strftime('%m/%d', created_at) = ?", d.strftime('%m/%d'))
Assuming that you are using mysql:
User.where(["DAY(created_at) = ? AND MONTH(created_at) = ?", date.day, date.month])
Assume RDBMS is MySQL and you have form with combobox to select month and/or date_of_months, may be you could make a named_scope, for example :
scope :by_date_or_month, lambda { |date, month| {:conditions => ["DAYOFMONTH(created_at) = ? or MONTH(created_at) = ?", date, month]}}
Test from IRB :
Model.by_date_or_month(31,8)
Model.by_date_or_month(nil,8)

Resources