क्या आप रेल 3 खोज में किसी तिथि की तुलना में अधिक कर सकते हैं?


125

मेरे पास रेल 3 में यह खोज है:

Note.where(:user_id => current_user.id, :notetype => p[:note_type], :date => p[:date]).order('date ASC, created_at ASC')

लेकिन मुझे इस :date => p[:date]शर्त की जरूरत है कि मैं इसके समकक्ष हो :date > p[:date]। मैं यह कैसे कर सकता हूँ? पढ़ने के लिए धन्यवाद।

जवाबों:


226
Note.
  where(:user_id => current_user.id, :notetype => p[:note_type]).
  where("date > ?", p[:date]).
  order('date ASC, created_at ASC')

या आप सब कुछ SQL संकेतन में बदल सकते हैं

Note.
  where("user_id = ? AND notetype = ? AND date > ?", current_user.id, p[:note_type], p[:date]).
  order('date ASC, created_at ASC')

2
क्या यह सुरक्षित है? मेरा मतलब है अगर p [: date] उपयोगकर्ता इनपुट से आया है, तो क्या यह SQL इंजेक्शन का कारण बन सकता है?
मद्धासिरवान

7
इसकी वजह से सुरक्षित है where()where()स्वचालित रूप से उपयोग करने से इनपुट बच जाता है।
Simone Carletti

34
सिमोन की टिप्पणी पूरी तरह से सच नहीं है; where()स्वचालित रूप से इनपुट से बच जाता है जब इसका उपयोग चर के स्थान पर प्रश्न-चिह्न के साथ ऊपर दिखाए गए प्रारूप में किया जाता है, बाद में उन्हें फ़ंक्शन कॉल में सूचीबद्ध किया जाता है। इस तरह से इसका इस्तेमाल करना सुरक्षित नहीं है:Note.where("date > #{p[:date]}")
bdx

4
यह भी ध्यान देने योग्य है, उन मामलों की where("user_id = ?",current_user.id)तुलना where(user_id: current_user.id)में जोखिम भरा है जहां आप उन मॉडलों को मर्ज करते हैं जिनमें दोनों का user_idक्षेत्र है। कच्चे एसक्यूएल संकेतन का उपयोग करने का मतलब है कि आपको टेबल स्पष्टीकरण को स्वयं शामिल करने की आवश्यकता है, जैसे where("notes.user_id = ?",current_user.id):।
DreadPirateShawn

1
आपको इससे सावधान रहना चाहिए, क्योंकि समय क्षेत्र। जब आप उपयोग करते हैं, जहां "" सीधे डेटाबेस में जाते हैं, और डेटाबेस में दिनांक UTC में सहेजे जाते हैं, लेकिन आपको उदाहरण के लिए UTC + 5 में होना चाहिए, और यह सही नहीं होगा। तो ऐसा करने से पहले अपने वर्तमान UTC में p [दिनांक] को परिवर्तित करना सुनिश्चित करें
पाउलो तरुड़

70

यदि आप उन समस्याओं से टकराते हैं जहाँ स्तंभ नाम अस्पष्ट हैं, तो आप कर सकते हैं:

date_field = Note.arel_table[:date]
Note.where(user_id: current_user.id, notetype: p[:note_type]).
     where(date_field.gt(p[:date])).
     order(date_field.asc(), Note.arel_table[:created_at].asc())

2
किसी कारण के लिए, मुझे एक कॉलम के साथ एक त्रुटि मिल रही थी जिसका उपयोग सिमोन के "जहां" पोस्टग्रेक्यूएल सर्वर पर "जहां" विधि का उपयोग नहीं किया गया था, लेकिन इसने SQLite में काम किया। आपका तरीका दोनों पर काम करता है।
plackemacher

2

आप उपयोग करने की कोशिश कर सकते हैं:

where(date: p[:date]..Float::INFINITY)

sql में बराबर

WHERE (`date` >= p[:date])

परिणाम है:

Note.where(user_id: current_user.id, notetype: p[:note_type], date: p[:date]..Float::INFINITY).order(:fecha, :created_at)

और मैं भी बदल गया हूं

order('date ASC, created_at ASC')

के लिये

order(:fecha, :created_at)

0

नियम 6.1 ने whereशर्तों में तुलना ऑपरेटरों के लिए एक नया 'वाक्यविन्यास' जोड़ा , उदाहरण के लिए:

Post.where('id >': 9)
Post.where('id >=': 9)
Post.where('id <': 3)
Post.where('id <=': 3)

तो आपकी क्वेरी को इस प्रकार फिर से लिखा जा सकता है:

Note
  .where(user_id: current_user.id, notetype: p[:note_type], 'date >', p[:date])
  .order(date: :asc, created_at: :asc)

यहां पीआर के लिए एक लिंक है जहां आप अधिक उदाहरण पा सकते हैं।

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