Bagaimana cara mendapatkan rekor yang dibuat hari ini oleh Rails Activerecord?

112

Bagaimana saya harus menulis pernyataan bersyarat ketika saya ingin mendapatkan semua rekaman yang dibuat hari ini?

Victor Lam
sumber

Jawaban:

220
Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)

PS: Jawaban ini sudah dimodifikasi karena jawaban Harish Shetty lebih baik dari saya. Karena jawaban saya diterima. Saya telah memperbarui jawaban ini untuk dukungan komunitas

Mohit Jain
sumber
4
Seseorang mungkin melakukan Post.where (create_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira
1
Tidak ada gunanya memeriksa untuk melihat apakah sesuatu telah dibuat sebelum akhir hari ini (karena besok belum terjadi).
jakeonrails
4
Meskipun Post.where("created_at >= ?", Time.zone.now.beginning_of_day)sangat pintar, saya akan mendukung Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Ada gunanya melakukan dengan cara yang dapat Anda lakukan untuk memanipulasi waktu. Misalnya, jika Anda menguji, Anda mungkin akan memanipulasi waktu dan kemudian opsi pertama tidak akan berfungsi. Anda ingin menghindari kemungkinan kegagalan di masa mendatang yang mungkin memerlukan waktu debug.
lucasarruda
121

Saya tahu pertanyaan ini memiliki jawaban yang diterima. Solusi yang disarankan dalam jawaban yang diterima dapat menyebabkan masalah kinerja saat ukuran tabel bertambah.

Biasanya, jika Anda melakukan pencarian berdasarkan created_atkolom, tambahkan indeks pada tabel di file migrasi Anda.

add_index :posts, :created_at

Sekarang, untuk mencari rekaman yang dibuat hari ini:

Rel 3/4

Post.where("created_at >= ?", Time.zone.now.beginning_of_day)

Untuk mencari postingan yang dibuat pada hari tertentu.

Post.where(:created_at => (date.beginning_of_day..date.end_of_day))

--------- ATAU -------------

Tambahkan metode statis ke model Anda

class Post < ActiveRecord::Base
  def self.today
    where("created_at >= ?", Time.zone.now.beginning_of_day)
  end
end

Post.today #returns posts today

Rel 2

Post.all(:conditions => ["created_at >= ?", Time.zone.now.beginning_of_day])

--------- ATAU -------------

Tambahkan name_scope ke model Anda

class Post < ActiveRecord::Base    
  named_scope :today, lambda { 
    {
      :conditions => ["created_at >= ?", Time.zone.now.beginning_of_day]
    }
  }
end

Post.today #returns posts today
Harish Shetty
sumber
1
Poin bagus tentang pengindeksan. Hanya ingin mengklarifikasi bahwa scopecontoh dalam posting ini hanya untuk Rails 3, karena sepertinya berada di bawah judul Rails 2. Di Rails 2, Anda harus menggunakan named_scopedaripada scope. Selain itu, di Rails 3, Anda dapat menggunakan metode kelas yang setara def self.today where("created_at >= ?", Time.now.beginning_of_day) end yang mungkin lebih bersih daripada menggunakan cakupan dalam kasus ini, karena memungkinkan Anda untuk mengabaikan lambda.
evanrmurphy
@evanrmurphy, Terima kasih telah mencatatnya. Saya memiliki jawaban yang pasti.
Harish Shetty
@evanrmurphy dapat / haruskah Anda merevisi komentar Anda dari "Rails 3 saja" menjadi "Rails 3 dan lebih tinggi"?
kaichanvong
@kaichanvong Saya tidak terbiasa dengan Rails 4, jadi saya ingin mengatakan "Rails 3 (dan lebih besar?)" tetapi JADI tidak mengizinkan saya mengedit komentar: - /
evanrmurphy
30

MySQL:

Model.all :condition => ["DATE(created_at) = ?", Date.today] # rails 2
Model.where("DATE(created_at) = ?", Date.today) # rails 3

PostgreSQL:

Model.all :condition => ["created_at::date = ?", Date.today] # rails 2
Model.where("created_at::date = ?", Date.today) # rails 3
jigfox.dll
sumber
19

Jawaban Mohit Jain diadaptasi untuk Rails3

Model.where "DATE(created_at) = DATE(?)", Time.now
thekindofme
sumber
16

Rails 5.1 memiliki all_dayhelper yang berguna di sini.

Post.where(created_at: Date.today.all_day)

atau

Post.where(created_at: Date.parse("YYYY-MM-DD").all_day)
StevenClontz
sumber
9

Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)

Ini "Namescopes" atribut dengan table_name.

Rafael Oliveira
sumber
5

model.rb

scope :posted_today, -> { posted_between_period(Time.now.midnight, Time.now.end_of_day) }

posts_controller.rb

Post.posted_today
Parthiv
sumber
2
@Pathiv, between_periodterlihat menarik. Saya tidak menemukan dokumentasi apa pun untuk itu. Bisakah Anda memberikan beberapa tautan? Bagaimana rel memilih kolom untuk perbandingan?
Harish Shetty
1

Untuk beberapa alasan, tidak ada solusi lain di posting ini atau yang lain di StackOverflow yang berfungsi untuk saya (menggunakan Rails 4.2.4 dan Ruby 2.2.3p173). Ini adalah satu-satunya kueri yang dapat saya gunakan dengan database Postgres saya:

Post.where("created_at >= TIMESTAMP 'now'")
Tim S
sumber
-1

Untuk menanyakan catatan yang dibuat mulai hari ini

Gunakan ruang lingkup dengan arel

class Post < ActiveRecord::Base    
  scope :create_from_today, -> {
    where(arel_table[:created_at].gteq(Time.zone.now.beginning_of_day))
  }
end

Lalu kita bisa menggunakannya

today_posts = Post.created_from_today
Hieu Pham
sumber
where('created_at >= now()')hanya akan menemukan item di mana create_at berada di masa mendatang.
Humas Whitehead
Ya saya akan menghapusnya dari jawaban, tangkapan bagus terima kasih
Hieu Pham
Masalah yang Anda hadapi sekarang adalah bahwa catatan yang ditandai dengan tanggal yang akan datang akan disajikan dan juga untuk hari ini. Jika Anda mencoba menghindari penggunaan di antara keduanya, Anda harus menentukannya .lteq(Time.zone.now.end_of_day))juga.
PR Whitehead
-4

Di rel 4.2.3 untuk mendapatkan catatan yang dibuat hari ini, menggunakan mysql gunakan yang berikut ini.

@usergoals = Goal.where ("userid =: userid dan Tanggal (create_at) =: date", {userid: params [: id], date: Date.today})

di sini saya menggunakan beberapa kondisi jika Anda mau, Anda dapat mengeditnya untuk satu kondisi.

santu
sumber