रेल मॉडल जहां नहीं के बराबर है


127

मैं अपने डेटाबेस में एक समान स्थिति में रिकॉर्ड कैसे प्राप्त कर सकता हूं? मेरे पास अब यह है, लेकिन क्या एक फैंसी रेल-बोलने का तरीका है?

GroupUser.where('user_id != ?',me)

आपके पास जो कुछ भी है वह बहुत अच्छा है रेल्स 3 तरह से यह मुझे लगता है।
Spyros

जवाबों:


229

रेल में 4.x ( http://edgeguides.rubyonrails.org/active_record_querying.html#not-conditions देखें )

GroupUser.where.not(user_id: me)

रेल में 3.x

GroupUser.where(GroupUser.arel_table[:user_id].not_eq(me))

लंबाई को छोटा करने के लिए, आप GroupUser.arel_tableएक चर में स्टोर कर सकते हैं या यदि मॉडल के अंदर GroupUserस्वयं scopeका उपयोग कर सकते हैं जैसे, ए में , आप arel_table[:user_id]इसके बजाय उपयोग कर सकते हैंGroupUser.arel_table[:user_id]

@ Jbearden के उत्तर के लिए 4.0 सिंटैक्स क्रेडिट का पालन ​​करता है


संघों में क्या है? - has_many: group_users, -> {where.not (स्थिति: "अस्वीकृत")}, के माध्यम से:: समूह,
विदेशी_की

4
एक साइड नोट के रूप में, यह अच्छी तरह से जंजीर का काम करता है:GroupUser.where(other_condition: true).where.not(user_id: user_id)
एनरिको कारलेसो


26

एकमात्र तरीका जिसे आप पा सकते हैं, वह मेटावेयर के साथ है ।

MetaWhere एक नए चचेरे भाई जो कहा जाता है है Squeel जो इस तरह कोड की अनुमति देता है:

GroupUser.where{user_id != me}

यह बिना कहे चला जाता है, कि अगर यह एकमात्र प्रतिक्षेपक है जिसे आप बनाने जा रहे हैं, तो यह एक मणि का उपयोग करने के लायक नहीं है और मैं सिर्फ उसी चीज़ के साथ रहूँगा जो आपको मिला था। स्क्वील उन स्थितियों में उपयोगी है जहां आपके पास रूबी कोड के साथ बातचीत करने वाले कई जटिल प्रश्न हैं।


4
मेटावेयर महान है, लेकिन यह कार्य एक रत्न को जोड़े बिना किया जा सकता है।
tybro0103

1
@ tybro0103 बेशक कार्य किया जा सकता है (और जिस तरह से ओपी कर रहा है वह पूरी तरह से ठीक है), सवाल यह है कि यह कट्टरता है। इसलिए अगर आपको लगता है कि यह बिना मणि के किया जा सकता है, तो मुझे बहुत दिलचस्पी होगी कि मैं ऐसा कैसे करूं।
जैकब हैम्पल

विक्रांत का जवाब एक समाधान प्रदान करता है जिसमें एसक्यूएल या अन्य रत्न शामिल नहीं है। लेकिन, मैं सही हूं, आपका जवाब निश्चित रूप से सबसे कोडर-फ्रेंडली / फैंसी है।
tybro0103

1
इस तरह के एक सरल कार्य को पूरा करने के लिए एक रत्न जोड़ना। एक bazooka के साथ एक
mozzy मारना

यह ओवरकिल है।
कोर्टीमास

23

रेल 4:

यदि आप समान और समान दोनों का उपयोग नहीं करना चाहते हैं , तो आप उपयोग कर सकते हैं:

user_id = 4
group_id = 27
GroupUser.where(group_id: group_id).where.not(user_id: user_id)

(। यानी आप ऑपरेटरों की एक किस्म का उपयोग करना चाहते हैं >, <), कुछ बिंदु पर आप निम्न के अंकन स्विच कर सकते हैं:

GroupUser.where("group_id > ? AND user_id != ?", group_id, user_id)

किस बारे में GroupUser.where(group_id: group_id).where.not(user_id: user_id)?
एनरिको कारलेसो

@EnricoCarlesso पोस्ट करने के लिए धन्यवाद। मैंने आपके सुझाव को शामिल करने के लिए अपना उत्तर अपडेट किया। धन्यवाद।
रिक स्मिथ

9

संघों के साथ काम करते समय आपको हमेशा SQL क्वेरी में तालिका का नाम शामिल करना चाहिए ।

वास्तव में यदि किसी अन्य तालिका में user_idस्तंभ है और आप दोनों तालिकाओं से जुड़ते हैं, तो आपके पास SQL ​​क्वेरी (अर्थात परेशानियाँ) में एक अस्पष्ट स्तंभ नाम होगा।

तो, आपके उदाहरण में:

GroupUser.where("groups_users.user_id != ?", me)

या थोड़ा और क्रिया:

GroupUser.where("#{table_name}.user_id IS NOT ?", me)

ध्यान दें कि यदि आप हैश का उपयोग कर रहे हैं, तो आपको इसके बारे में चिंता करने की आवश्यकता नहीं है क्योंकि रेल आपके लिए इसका ध्यान रखती है:

GroupUser.where(user: me)

Rails 4 में, जैसा कि @ dr4k3 ने कहा है, क्वेरी विधि notजोड़ी गई है:

GroupUser.where.not(user: me)

6

रेल 3 में, मैं कुछ भी कट्टर नहीं जानता। हालाँकि, मुझे यकीन नहीं है कि अगर आप जागरूक हैं, तो आपकी समान स्थिति (user_id) पूर्ण मानों से मेल नहीं खाती। यदि आप ऐसा चाहते हैं, तो आपको कुछ इस तरह करना होगा:

GroupUser.where("user_id != ? OR user_id IS NULL", me)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.