ActiveRecord के बीच की तारीख रेल


171

मुझे एक दिन में की गई टिप्पणियों को क्वेरी करने की आवश्यकता है। क्षेत्र मानक टाइमस्टैम्प का हिस्सा है, है created_at। चयनित तिथि एक से आ रही है date_select

मैं इसे करने के ActiveRecordलिए कैसे उपयोग कर सकता हूं ?

मुझे कुछ इस तरह की आवश्यकता है:

"SELECT * FROM comments WHERE created_at BETWEEN '2010-02-03 00:00:00' AND '2010-02-03 23:59:59'"

जवाबों:


402

बस एक नोट जो वर्तमान में स्वीकृत उत्तर रेल में दर्शाया गया है 3. आपको इसके बजाय ऐसा करना चाहिए:

Comment.where(:created_at => @selected_date.beginning_of_day..@selected_date.end_of_day)

या, यदि आप शुद्ध स्ट्रिंग शर्तों का उपयोग करना चाहते हैं या करना चाहते हैं , तो आप कर सकते हैं:

Comment.where('created_at BETWEEN ? AND ?', @selected_date.beginning_of_day, @selected_date.end_of_day)

9
Day.where (: reference_date => 6.months.ago..Time.now) काम करता है, धन्यवाद
boulder_ruby

4
क्या यह एक विशाल रेंज ऑब्जेक्ट नहीं बनायेगा?
कास्पर ग्रुबे

3
@ कैस्परग्रुबे यदि आप रेंज का इस्तेमाल खुद ही करेंगे, लेकिन रेल सिर्फ पहले और आखिरी मूल्यों का उपयोग करती है
डेक्स

4
@KasperGrubbe @Dex यह रेल नहीं है जो ऐसा करती है। रूबी में रेंज क्लास केवल निचले और ऊपरी सीमा को बचाता है। यह irb में ठीक चलता है: 1..1000000000000मैं इस बात पर स्पष्ट नहीं हूँ कि 'अपने आप से सीमा का उपयोग करने' का क्या मतलब है
Connor Clark

11
+1 हम इसे एक स्कोप भी बना सकते हैं: scope :between, -> (a, b) { where(created_at: a..b) }
15'15

48

मैं व्यक्तिगत रूप से इसे और अधिक पठनीय और फिर से उपयोग करने योग्य बनाने के लिए एक गुंजाइश बनाएगा:

आप Comment.rb में, आप एक गुंजाइश परिभाषित कर सकते हैं:

scope :created_between, lambda {|start_date, end_date| where("created_at >= ? AND created_at <= ?", start_date, end_date )}

फिर क्वेरी के बीच बनाया गया:

@comment.created_between(1.year.ago, Time.now)

आशा करता हूँ की ये काम करेगा।


4
बहुत साफ दृष्टिकोण ... एकदम सही !!
जोसेफ एन।

इस उत्तर को वापस लेने के लिए क्योंकि मैंने इस मुद्दे की खोज की थी। सिंटैक्स में गलत तरीके से अनुमान लगाया गया, #between?एक सीमा स्वीकार की गई।
तास

28

रेल 5.1 ने एक नई तिथि सहायक विधि शुरू की all_day, देखें: https://github.com/rails/rails/pull/24930

>> Date.today.all_day
=> Wed, 26 Jul 2017 00:00:00 UTC +00:00..Wed, 26 Jul 2017 23:59:59 UTC +00:00

यदि आप रेल 5.1 का उपयोग कर रहे हैं, तो क्वेरी इस तरह दिखाई देगी:

Comment.where(created_at: @selected_date.all_day)

1
शानदार। यह वास्तव में ActiveSupport रत्न (और बाद में संपूर्ण ActiveRecord पारिस्थितिक तंत्र) का हिस्सा है, इसलिए यह जेल के बाहर भी काम करता है! बस require 'active_record'और आप सब सेट हैं!
मास्टर ऑफ डक्स

24

यह कोड आपके लिए काम करना चाहिए:

Comment.find(:all, :conditions => {:created_at => @selected_date.beginning_of_day..@selected_date.end_of_day})

अधिक जानकारी के लिए समय गणना पर एक नज़र है

नोट: यह कोड पदावनत है । यदि आप रेल 3.1 / 3.2 का उपयोग कर रहे हैं तो उत्तर से कोड का उपयोग करें


ठीक है, लेकिन इस फॉर्म से मुझे यह मिलता है: {"लिखित_त (4i)" => "18", "लिखित_त (5i)" => "56", "सामग्री" => "rrrrrr", "लिखित_त (1i)" = > "2010", "लिखित_त (2i)" => "5", "लिखित_त (3i)" => "4"} मैं शुरुआत_ऑफडे का उपयोग करने के लिए ऑब्जेक्ट कैसे बना सकता हूं?
rtacconi 19

यह वही है जो मुझे चाहिए: purab.wordpress.com/2009/06/16/…
rtacconi

2
मुझे यह तरीका स्वीकृत उत्तर से अधिक पसंद है क्योंकि यह db-level date()फ़ंक्शन पर निर्भर नहीं करता है; यह संभावित रूप से अधिक db स्वतंत्र है।
क्रेग वाकर

10

मैंने इस कोड को यह देखने के लिए चलाया कि चेक किया गया जवाब काम करता है या नहीं, और इसे सही करने के लिए तारीखों के आसपास स्वैप करने की कोशिश करनी होगी। यह काम किया -

Day.where(:reference_date => 3.months.ago..Time.now).count
#=> 721

यदि आप सोच रहे हैं कि उत्पादन 36 होना चाहिए था, तो इस पर विचार करें, सर, 3 लोगों के लिए 3 दिन कितने दिन हैं?



5

मैं 3 डॉट्स का उपयोग कर रहा हूं, इसके बजाय 2. तीन डॉट्स आपको एक रेंज देता है जो शुरुआत में खुली है और अंत में बंद है, इसलिए यदि आप बाद के रेंज के लिए 2 क्वेरी करते हैं, तो आप उसी पंक्ति को वापस नहीं ला सकते हैं। दोनों।

2.2.2 :003 > Comment.where(updated_at: 2.days.ago.beginning_of_day..1.day.ago.beginning_of_day)
Comment Load (0.3ms)  SELECT "comments".* FROM "comments" WHERE ("comments"."updated_at" BETWEEN '2015-07-12 00:00:00.000000' AND '2015-07-13 00:00:00.000000')
=> #<ActiveRecord::Relation []> 
2.2.2 :004 > Comment.where(updated_at: 2.days.ago.beginning_of_day...1.day.ago.beginning_of_day)
Comment Load (0.3ms)  SELECT "comments".* FROM "comments" WHERE ("comments"."updated_at" >= '2015-07-12 00:00:00.000000' AND "comments"."updated_at" < '2015-07-13 00:00:00.000000')
=> #<ActiveRecord::Relation []> 

और, हाँ, हमेशा एक गुंजाइश का उपयोग करने के लिए अच्छा है!


4

यदि आप केवल एक दिन प्राप्त करना चाहते हैं तो यह इस तरह से आसान होगा:

Comment.all(:conditions => ["date(created_at) = ?", some_date])

4

कई तरीके हैं। आप इस विधि का उपयोग कर सकते हैं:

start = @selected_date.beginning_of_day
end = @selected_date.end_of_day
@comments = Comment.where("DATE(created_at) BETWEEN ? AND ?", start, end)

या यह:

@comments = Comment.where(:created_at => @selected_date.beginning_of_day..@selected_date.end_of_day)

4

इस पर एक डिफ़ॉल्ट सक्रिय रिकॉर्ड व्यवहार होना चाहिए जो मुझे लगता है। क्वेरी की तारीखें कठिन हैं, खासकर जब टाइमज़ोन शामिल हो।

वैसे भी, मैं उपयोग:

  scope :between, ->(start_date=nil, end_date=nil) {
    if start_date && end_date
      where("#{self.table_name}.created_at BETWEEN :start AND :end", start: start_date.beginning_of_day, end: end_date.end_of_day)
    elsif start_date
      where("#{self.table_name}.created_at >= ?", start_date.beginning_of_day)
    elsif end_date
      where("#{self.table_name}.created_at <= ?", end_date.end_of_day)
    else
      all
    end
  }

1

आप दिनांक के बीच रिकॉर्ड खोजने के लिए मणि के नीचे का उपयोग कर सकते हैं,

इस मणि का उपयोग करना काफी आसान है और अधिक स्पष्ट है स्टार द्वारा इस मणि का उपयोग किया जा रहा है और एपीआई अधिक स्पष्ट और प्रलेखन भी अच्छी तरह से समझाया गया है।

Post.between_times(Time.zone.now - 3.hours,  # all posts in last 3 hours
                  Time.zone.now)

यहाँ आप हमारे क्षेत्र को भी पास कर सकते हैं Post.by_month("January", field: :updated_at)

कृपया दस्तावेज़ देखें और इसे आज़माएँ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.