Làm thế nào để có được bản ghi được tạo ngày hôm nay bởi Activerecord rails?


Câu trả lời:


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

Tái bút: Câu trả lời này đã được sửa đổi vì câu trả lời của Harish Shetty tốt hơn câu trả lời của tôi. Như câu trả lời của tôi được chấp nhận một. Tôi đã cập nhật câu trả lời này để hỗ trợ cộng đồng


4
Người ta có thể làm Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira

1
Không có ích gì khi kiểm tra xem liệu thứ gì đó đã được tạo trước khi kết thúc ngày hôm nay (vì ngày mai chưa xảy ra).
jakeonrails

4
Trong khi Post.where("created_at >= ?", Time.zone.now.beginning_of_day)rất thông minh, tôi sẽ xác nhận Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Có một điểm để làm theo cách bạn có thể điều khiển thời gian. Ví dụ: nếu bạn đang thử nghiệm, bạn có thể sẽ thao túng thời gian và sau đó tùy chọn đầu tiên sẽ không hoạt động. Bạn muốn tránh loại lỗi có thể xảy ra trong tương lai mà có thể sẽ mất một thời gian gỡ lỗi.
lucasarruda

121

Tôi biết câu hỏi này có một câu trả lời được chấp nhận. Giải pháp được đề xuất trong câu trả lời được chấp nhận có thể gây ra các vấn đề về hiệu suất khi kích thước bảng tăng lên.

Thông thường, nếu bạn thực hiện tra cứu dựa trên created_atcột, hãy thêm chỉ mục trên bảng trong tệp di chuyển của bạn.

add_index :posts, :created_at

Bây giờ, để tra cứu các bản ghi được tạo ngày hôm nay:

Đường ray 3/4

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

Để tra cứu các bài viết được tạo vào một ngày cụ thể.

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

--------- HOẶC -------------

Thêm một phương thức tĩnh vào mô hình của bạn

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

Post.today #returns posts today

Đường ray 2

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

--------- HOẶC -------------

Thêm tên_mặt kính vào mô hình của bạn

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

Post.today #returns posts today

1
Điểm tuyệt vời về lập chỉ mục. Tôi chỉ muốn làm rõ rằng scopeví dụ trong bài đăng này chỉ dành cho Rails 3, vì có vẻ như nó nằm dưới tiêu đề Rails 2. Trong Rails 2, bạn sẽ cần sử dụng named_scopehơn là scope. Ngoài ra, trong Rails 3, bạn có thể tương tự sử dụng một phương thức lớp def self.today where("created_at >= ?", Time.now.beginning_of_day) end có thể rõ ràng hơn so với sử dụng phạm vi trong trường hợp này, vì nó cho phép bạn bỏ qua lambda.
evanrmurphy,

@evanrmurphy, Cảm ơn bạn đã lưu ý điều đó. Tôi đã cố định câu trả lời.
Harish Shetty,

@evanrmurphy có thể / bạn có nên sửa đổi nhận xét của mình từ "Chỉ dành cho Rails 3" thành "Rails 3 trở lên" không?
kaichanvong

@kaichanvong Tôi không quen thuộc với Rails 4, vì vậy tôi muốn nói "Rails 3 (và lớn hơn?)" nhưng SO sẽ không cho phép tôi chỉnh sửa bình luận: - /
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

19

Câu trả lời của Mohit Jain được điều chỉnh cho Rails3

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

16

Rails 5.1 có một trình all_daytrợ giúp hữu ích ở đây.

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

hoặc là

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

9

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

Điều này "phân tích tên" thuộc tính với table_name.


5

model.rb

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

posts_controller.rb

Post.posted_today

2
@Pathiv, có between_periodvẻ thú vị. Tôi không tìm thấy bất kỳ tài liệu nào cho nó. Bạn có thể cung cấp một số liên kết? Làm thế nào để ray chọn cột để so sánh?
Harish Shetty

1

Vì một số lý do, không có giải pháp nào khác trong bài đăng này cũng như các giải pháp khác trên StackOverflow phù hợp với tôi (sử dụng Rails 4.2.4 và Ruby 2.2.3p173). Đây là truy vấn duy nhất mà tôi có thể làm việc với cơ sở dữ liệu Postgres của mình:

Post.where("created_at >= TIMESTAMP 'now'")

-1

Để truy vấn các bản ghi được tạo từ hôm nay

Sử dụng phạm vi với arel

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

Sau đó, chúng ta có thể sử dụng nó

today_posts = Post.created_from_today

where('created_at >= now()')sẽ chỉ tìm thấy các mục có tên_tạo_tạo trong tương lai.
PR Whitehead

Vâng, tôi xin xóa nó khỏi câu trả lời, rất hay, cảm ơn
Hieu Pham

Vấn đề bạn gặp phải bây giờ là các bản ghi được đánh dấu bằng các ngày trong tương lai sẽ được trình bày cũng như các bản ghi cho ngày hôm nay. Nếu bạn đang cố gắng tránh sử dụng giữa, bạn cũng nên chỉ định .lteq(Time.zone.now.end_of_day)).
PR Whitehead

-4

Trong rails 4.2.3 để lấy các bản ghi được tạo ngày hôm nay, sử dụng mysql, hãy sử dụng như sau.

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

ở đây tôi đang sử dụng nhiều điều kiện nếu bạn muốn, bạn có thể chỉnh sửa nó cho một điều kiện.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.