मैं 200 से अधिक आईडी वाले सभी उपयोगकर्ताओं को खोजने की कोशिश कर रहा हूं, लेकिन मुझे विशिष्ट वाक्यविन्यास के साथ कुछ परेशानी हो रही है।
User.where(:id > 200)
तथा
User.where("? > 200", :id)
दोनों असफल रहे।
कोई सुझाव?
मैं 200 से अधिक आईडी वाले सभी उपयोगकर्ताओं को खोजने की कोशिश कर रहा हूं, लेकिन मुझे विशिष्ट वाक्यविन्यास के साथ कुछ परेशानी हो रही है।
User.where(:id > 200)
तथा
User.where("? > 200", :id)
दोनों असफल रहे।
कोई सुझाव?
जवाबों:
इसे इस्तेमाल करे
User.where("id > ?", 200)
?
इनलाइन करने के बजाय उपयोग करने को प्राथमिकता देना है 200
?
मैंने केवल रेल 4 में इसका परीक्षण किया है, लेकिन where
इस व्यवहार को प्राप्त करने के लिए हैश के साथ एक सीमा का उपयोग करने का एक दिलचस्प तरीका है ।
User.where(id: 201..Float::INFINITY)
SQL उत्पन्न करेगा
SELECT `users`.* FROM `users` WHERE (`users`.`id` >= 201)
उसी के साथ कम के लिए किया जा सकता है -Float::INFINITY
।
मैंने एसओ पर तारीखों के साथ ऐसा करने के बारे में पूछते हुए एक समान प्रश्न पोस्ट किया ।
>=
बनाम >
लोगों के माध्यम से खुदाई करने और टिप्पणियों की बातचीत का अनुसरण करने से बचने के लिए यहां मुख्य आकर्षण हैं।
ऊपर दी गई विधि केवल एक >=
क्वेरी उत्पन्न करती है और ए नहीं>
। इस विकल्प को संभालने के कई तरीके हैं।
असतत संख्या के लिए
आप number_you_want + 1
ऊपर की तरह एक रणनीति का उपयोग कर सकते हैं जहां मैं उपयोगकर्ताओं के साथ दिलचस्पी रखता हूं id > 200
लेकिन वास्तव में तलाश करता हूं id >= 201
। यह पूर्णांकों और संख्याओं के लिए ठीक है जहां आप ब्याज की एक इकाई द्वारा वृद्धि कर सकते हैं।
यदि आपके पास एक निरंतर नाम वाले कुएं में निकाली गई संख्या है तो यह एक नज़र में पढ़ने और समझने में सबसे आसान हो सकता है।
उलटा तर्क
हम इस तथ्य का उपयोग कर सकते हैं x > y == !(x <= y)
और जहां चेन का उपयोग नहीं करते हैं।
User.where.not(id: -Float::INFINITY..200)
जो SQL उत्पन्न करता है
SELECT `users`.* FROM `users` WHERE (NOT (`users`.`id` <= 200))
यह पढ़ने और तर्क करने के लिए एक अतिरिक्त सेकंड लेता है, लेकिन गैर असतत मूल्यों या स्तंभों के लिए काम करेगा जहां आप + 1
रणनीति का उपयोग नहीं कर सकते ।
अरेल की मेज
यदि आप फैंसी प्राप्त करना चाहते हैं तो आप इसका उपयोग कर सकते हैं Arel::Table
।
User.where(User.arel_table[:id].gt(200))
SQL उत्पन्न करेगा
"SELECT `users`.* FROM `users` WHERE (`users`.`id` > 200)"
विवरण इस प्रकार हैं:
User.arel_table #=> an Arel::Table instance for the User model / users table
User.arel_table[:id] #=> an Arel::Attributes::Attribute for the id column
User.arel_table[:id].gt(200) #=> an Arel::Nodes::GreaterThan which can be passed to `where`
यह दृष्टिकोण आपको सटीक एसक्यूएल मिलेगा जिसमें आप रुचि रखते हैं, हालांकि बहुत से लोग सीधे Arel तालिका का उपयोग नहीं करते हैं और इसे गन्दा और / या भ्रमित कर सकते हैं। आपको और आपकी टीम को पता चल जाएगा कि आपके लिए सबसे अच्छा क्या है।
रेल 5 में शुरू आप तिथियों के साथ भी ऐसा कर सकते हैं!
User.where(created_at: 3.days.ago..DateTime::Infinity.new)
SQL उत्पन्न करेगा
SELECT `users`.* FROM `users` WHERE (`users`.`created_at` >= '2018-07-07 17:00:51')
रूबी 2.6 जारी होने के बाद (25 दिसंबर, 2018) आप नई अनंत रेंज सिंटैक्स का उपयोग कर पाएंगे! इसके बजाय 201..Float::INFINITY
आप सिर्फ लिखने में सक्षम होंगे 201..
। इस ब्लॉग पोस्ट में अधिक जानकारी ।
where
मिलान का उपयोग कर सकते हैं । क्योंकि >
मैं सुझाव देता हूं कि >= (number_you_want + 1)
सादगी के लिए उपयोग करना । यदि आप वास्तव में यह सुनिश्चित करना चाहते हैं कि यह केवल एक >
क्वेरी है तो आप ARel तालिका तक पहुँच सकते हैं। प्रत्येक वर्ग जिसे विरासत में मिला है, ActiveRecord
उसके पास एक arel_table
गेट्टर विधि है जो Arel::Table
उस वर्ग के लिए वापस आती है । तालिका के स्तंभों को []
विधि के साथ एक्सेस किया जाता है User.arel_table[:id]
। यह वह रिटर्न है जिस पर Arel::Attributes::Attribute
आप कॉल कर सकते हैं gt
और पास कर सकते हैं 200
। इसके बाद इसे पारित किया जा सकता है where
। उदा User.where(User.arel_table[:id].gt(200))
।
User.where(created_at: 3.days.ago..DateTime::Infinity.new)
।
WHERE (users.created_at >= '2016-04-09 14:31:15' AND users.created_at < #<Date::Infinity:0x00>)
(तालिका के चारों ओर पीछे की ओर टिक और एसओ टिप्पणी प्रारूप के लिए छोड़ दिया गया स्तंभ नाम)।
यदि आप अधिक सहज लेखन चाहते हैं, तो इसमें स्क्वील नामक एक मणि मौजूद है, जो आपको अपना निर्देश इस तरह लिखने देगा:
User.where{id > 200}
'ब्रेस' अक्षर {} और id
सिर्फ एक पाठ होने के नाते।
आपको केवल अपने Gemfile में स्क्वील जोड़ना है:
gem "squeel"
रूबी में जटिल एसक्यूएल स्टेटमेंट लिखते समय यह आपके जीवन को बहुत आसान बना सकता है।
एक और फैंसी संभावना है ...
User.where("id > :id", id: 100)
यदि आप कई स्थानों पर प्रतिस्थापित करना चाहते हैं, तो यह सुविधा आपको अधिक सहज प्रश्न बनाने की अनुमति देती है, उदाहरण के लिए ...
User.where("id > :id OR number > :number AND employee_id = :employee", id: 100, number: 102, employee: 1205)
यह ?
क्वेरी पर बहुत कुछ होने से अधिक अर्थ है ...
User.where("id > ? OR number > ? AND employee_id = ?", 100, 102, 1205)
मुझे अक्सर दिनांक फ़ील्ड (जहां तुलना ऑपरेटर बहुत सामान्य हैं) के साथ यह समस्या है।
मिहाई के उत्तर के बारे में विस्तार से बताने के लिए, जो मेरा मानना है कि एक ठोस दृष्टिकोण है।
मॉडल के लिए आप इस तरह से स्कोप जोड़ सकते हैं:
scope :updated_at_less_than, -> (date_param) {
where(arel_table[:updated_at].lt(date_param)) }
... और फिर अपने नियंत्रक में, या जहाँ भी आप अपने मॉडल का उपयोग कर रहे हैं:
result = MyModel.updated_at_less_than('01/01/2017')
... जोड़ों के साथ एक अधिक जटिल उदाहरण इस तरह दिखता है:
result = MyParentModel.joins(:my_model).
merge(MyModel.updated_at_less_than('01/01/2017'))
इस दृष्टिकोण का एक बड़ा फायदा यह है कि यह आपको विभिन्न स्कोपों से अपने प्रश्नों की रचना करने देता है और (b) जब आप दो बार एक ही तालिका में शामिल होते हैं तो alias टकराव से बचते हैं क्योंकि arel_table क्वेरी पीढ़ी के उस हिस्से को संभाल लेगा।
नियम 6.1 ने where
शर्तों में तुलना ऑपरेटरों के लिए एक नया 'वाक्यविन्यास' जोड़ा , उदाहरण के लिए:
Post.where('id >': 9)
Post.where('id >=': 9)
Post.where('id <': 3)
Post.where('id <=': 3)
तो आपकी क्वेरी को इस प्रकार फिर से लिखा जा सकता है:
User.where('id >': 200)
यहां पीआर के लिए एक लिंक है जहां आप अधिक उदाहरण पा सकते हैं।
छोटा:
User.where("id > 200")
where("id > ?", 200)
सिंटैक्स) का उपयोग करके SQL इंजेक्शन से बचना चाहता है । यह हासिल नहीं करता है।