[Ruby-on-rails] ActiveRecord / Rails के साथ कोई प्रश्न पूछने के लिए कैसे व्यक्त करें?


Answers

एफवाईआई, रेल 4 में, आप वाक्यविन्यास का उपयोग not कर सकते हैं:

Article.where.not(title: ['Rails 3', 'Rails 5'])
Question

बस इसे अपडेट करने के बाद से ऐसा लगता है कि बहुत से लोग इस पर आते हैं, यदि आप रेल 4 का उपयोग कर रहे हैं तो ट्रंग लेई और विनीविडीविची द्वारा दिए गए उत्तरों को देखें।

Topic.where.not(forum_id:@forums.map(&:id))

Topic.where(published:true).where.not(forum_id:@forums.map(&:id))

मुझे उम्मीद है कि एक आसान समाधान है जिसमें find_by_sql शामिल नहीं है, अगर नहीं तो मुझे लगता है कि काम करना होगा।

मुझे यह आलेख मिला जो इस संदर्भ में है:

Topic.find(:all, :conditions => { :forum_id => @forums.map(&:id) })

जो वही है

SELECT * FROM topics WHERE forum_id IN (<@forum ids>)

मैं सोच रहा हूं कि इसमें ऐसा करने का कोई तरीका NOT IN है, जैसे:

SELECT * FROM topics WHERE forum_id NOT IN (<@forum ids>)



जब आप रिक्त सरणी से पूछते हैं तो जहां ब्लॉक में सरणी में "<< 0" जोड़ें, तो यह "NULL" वापस नहीं लौटाता है और क्वेरी को तोड़ देता है।

Topic.where('id not in (?)',actions << 0)

यदि क्रियाएं खाली या खाली सरणी हो सकती हैं।




आप एर्नी मिलर द्वारा meta_where प्लगइन पर एक नज़र रखना चाह सकते हैं। आपका एसक्यूएल कथन:

SELECT * FROM topics WHERE forum_id NOT IN (<@forum ids>)

... इस तरह व्यक्त किया जा सकता है:

Topic.where(:forum_id.nin => @forum_ids)

रेलसकास्ट के रयान बेट्स ने मेटावेयर को समझाते हुए एक अच्छा स्क्रीनकास्ट बनाया।

सुनिश्चित नहीं है कि यह वही है जो आप खोज रहे हैं लेकिन मेरी आंखों के लिए यह निश्चित रूप से एम्बेडेड SQL क्वेरी से बेहतर दिखता है।




स्वीकार्य समाधान विफल रहता है अगर @forums खाली है। इसे काम करने के लिए मुझे करना पड़ा

Topic.find(:all, :conditions => ['forum_id not in (?)', (@forums.empty? ? '' : @forums.map(&:id))])

या, यदि रेल 3+ का उपयोग करना है:

Topic.where( 'forum_id not in (?)', (@forums.empty? ? '' : @forums.map(&:id)) ).all



एरियल का उपयोग करना:

topics=Topic.arel_table
Topic.where(topics[:forum_id].not_in(@forum_ids))

या, अगर पसंदीदा:

topics=Topic.arel_table
Topic.where(topics[:forum_id].in(@forum_ids).not)

और चूंकि रेल 4 पर:

topics=Topic.arel_table
Topic.where.not(topics[:forum_id].in(@forum_ids))

कृपया ध्यान दें कि अंत में आप फोरम_ड्स को आईडी सूची नहीं चाहते हैं, बल्कि एक सबक्वायरी, यदि ऐसा है तो आपको विषयों को प्राप्त करने से पहले ऐसा कुछ करना चाहिए:

@forum_ids = Forum.where(/*whatever conditions are desirable*/).select(:id)

इस तरह आप सब कुछ एक ही प्रश्न में प्राप्त करते हैं: कुछ ऐसा:

select * from topic 
where forum_id in (select id 
                   from forum 
                   where /*whatever conditions are desirable*/)

यह भी ध्यान दें कि अंततः आप ऐसा नहीं करना चाहते हैं, बल्कि एक जुड़ना चाहते हैं - जो अधिक कुशल हो सकता है।




इस तरह पठनीयता के लिए अनुकूलित करता है, लेकिन यह डेटाबेस प्रश्नों के संदर्भ में उतना कुशल नहीं है:

# Retrieve all topics, then use array subtraction to
# find the ones not in our list
Topic.all - @forums.map(&:id)



आप अपनी शर्तों में एसक्यूएल का उपयोग कर सकते हैं:

Topic.find(:all, :conditions => [ "forum_id NOT IN (?)", @forums.map(&:id)])