จะสร้างบันทึกวันนี้โดยราง activerecord ได้อย่างไร?


คำตอบ:


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

PS: คำตอบนี้ได้รับการแก้ไขเนื่องจากคำตอบของ Harish Shetty นั้นดีกว่าของฉัน เนื่องจากคำตอบของฉันเป็นที่ยอมรับ ฉันได้อัปเดตคำตอบนี้เพื่อรับการสนับสนุนจากชุมชน


4
อาจมีคนทำ Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira

1
ไม่มีประเด็นในการตรวจสอบว่ามีอะไรสร้างขึ้นก่อนสิ้นวันนี้หรือไม่ (เนื่องจากพรุ่งนี้ยังไม่เกิดขึ้น)
jakeonrails

4
ในขณะที่เป็นคนฉลาดมากผมจะรับรองPost.where("created_at >= ?", Time.zone.now.beginning_of_day) Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)มีจุดสำคัญในการดำเนินการในลักษณะที่คุณสามารถกำหนดเวลาได้ ตัวอย่างเช่นหากคุณกำลังทดสอบคุณอาจจะปรับเปลี่ยนเวลาและตัวเลือกแรกจะไม่ทำงาน คุณต้องการหลีกเลี่ยงความล้มเหลวที่อาจเกิดขึ้นในอนาคตซึ่งอาจต้องใช้เวลาในการดีบัก
lucasarruda

123

ฉันรู้ว่าคำถามนี้มีคำตอบที่เป็นที่ยอมรับ วิธีแก้ปัญหาที่แนะนำในคำตอบที่ยอมรับอาจทำให้เกิดปัญหาด้านประสิทธิภาพเมื่อขนาดตารางโตขึ้น

โดยทั่วไปหากคุณทำการค้นหาตามcreated_atคอลัมน์ให้เพิ่มดัชนีบนตารางในไฟล์การย้ายข้อมูลของคุณ

add_index :posts, :created_at

ตอนนี้ในการค้นหาระเบียนที่สร้างขึ้นในวันนี้:

ราง 3/4

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

เพื่อค้นหาโพสต์ที่สร้างขึ้นในวันใดวันหนึ่ง

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

--------- หรือ -------------

เพิ่มวิธีการคงที่ให้กับโมเดลของคุณ

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

Post.today #returns posts today

ราง 2

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

--------- หรือ -------------

เพิ่ม named_scope ให้กับโมเดลของคุณ

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

Post.today #returns posts today

1
จุดที่ดีเกี่ยวกับการจัดทำดัชนี แค่อยากจะชี้แจงว่าscopeตัวอย่างในโพสต์นี้มีไว้สำหรับ Rails 3 เท่านั้นเนื่องจากดูเหมือนว่าจะอยู่ภายใต้หัวข้อ Rails 2 ในรางที่ 2 คุณจะต้องใช้มากกว่าnamed_scope scopeนอกจากนี้ใน Rails 3 คุณสามารถใช้เมธอดคลาส def self.today where("created_at >= ?", Time.now.beginning_of_day) end ซึ่งอาจจะสะอาดกว่าการใช้ขอบเขตในกรณีนี้เนื่องจากอนุญาตให้คุณละทิ้งแลมด้าได้
evanrmurphy

@evanrmurphy ขอบคุณที่แจ้งให้ทราบ ฉันมีคำตอบที่แน่นอน
Harish Shetty

@evanrmurphy คุณสามารถ / ควรแก้ไขความคิดเห็นของคุณจาก "Rails 3 only" เป็น "Rails 3 and greater" หรือไม่
kaichanvong

@kaichanvong ฉันไม่คุ้นเคยกับ Rails 4 ดังนั้นฉันอยากจะพูดว่า "Rails 3 (และมากกว่า?)" แต่ SO จะไม่ให้ฉันแก้ไขความคิดเห็น: - /
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


16

Rails 5.1 มีตัวall_dayช่วยที่มีประโยชน์ที่นี่

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

หรือ

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)

"เนมสโคป" นี้เป็นแอตทริบิวต์ที่มี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 between_periodดูน่าสนใจ ฉันไม่พบเอกสารใด ๆ ขอลิงค์หน่อยได้ไหม รางเลือกคอลัมน์สำหรับการเปรียบเทียบอย่างไร?
Harish Shetty

1

ด้วยเหตุผลบางประการไม่มีวิธีแก้ปัญหาอื่นใดในโพสต์นี้หรือวิธีอื่น ๆ ใน StackOverflow ที่ใช้ได้กับฉัน (ใช้ Rails 4.2.4 และ Ruby 2.2.3p173) นี่เป็นแบบสอบถามเดียวที่ฉันสามารถใช้กับฐานข้อมูล Postgres ของฉันได้:

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

-1

เพื่อสอบถามระเบียนที่สร้างขึ้นตั้งแต่วันนี้

ใช้ขอบเขตกับ arel

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

จากนั้นเราสามารถใช้งานได้

today_posts = Post.created_from_today

where('created_at >= now()')จะพบเฉพาะรายการที่ created_at ในอนาคต
PR Whitehead

ใช่ฉันจะลบมันออกจากคำตอบขอบคุณที่จับได้
Hieu Pham

ปัญหาที่คุณพบในตอนนี้คือบันทึกที่มีเครื่องหมายวันที่ในอนาคตจะถูกนำเสนอเช่นเดียวกับข้อมูลสำหรับวันนี้ หากคุณกำลังพยายามหลีกเลี่ยงการใช้ระหว่างคุณควรระบุ.lteq(Time.zone.now.end_of_day))ด้วย
PR Whitehead

-4

ในราง 4.2.3 สำหรับการรับเรกคอร์ดที่สร้างขึ้นในวันนี้โดยใช้ mysql ใช้สิ่งต่อไปนี้

@usergoals = Goal.where ("userid =: userid และ Date (created_at) =: date", {userid: params [: id], date: Date.today})

ที่นี่ฉันใช้หลายเงื่อนไขหากคุณต้องการคุณสามารถแก้ไขได้สำหรับเงื่อนไขเดียว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.