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




ruby-on-rails (10)

बस इसे अपडेट करने के बाद से ऐसा लगता है कि बहुत से लोग इस पर आते हैं, यदि आप रेल 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>)

@Trung Lê उत्तर पर विस्तार करने के लिए, रेल 4 में आप निम्न कार्य कर सकते हैं:

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

और आप इसे एक कदम आगे ले जा सकते हैं। यदि आपको पहले प्रकाशित विषयों के लिए पहले फ़िल्टर करना होगा और फिर उन आईडी को फ़िल्टर करना होगा जिन्हें आप नहीं चाहते हैं, तो आप यह कर सकते हैं:

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

रेल 4 इसे इतना आसान बनाता है!


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

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

आप कुछ ऐसा करने की कोशिश कर सकते हैं:

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

आपको @forums.map(&:id).join(',') करने की आवश्यकता हो सकती है। मुझे याद नहीं है कि अगर रेल एक सीएसवी सूची में बहस करेंगे तो यह संख्यात्मक है।

आप यह भी कर सकते हैं:

# in topic.rb
named_scope :not_in_forums, lambda { |forums| { :conditions => ['forum_id not in (?)', forums.select(&:id).join(',')] }

# in your controller 
Topic.not_in_forums(@forums)

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

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

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

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

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

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*/)

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


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

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

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



मैं इसका उपयोग कर रहा हूँ:

Topic.where('id NOT IN (?)',actions)

जहां actions एक सरणी है: [1,2,3,4,5]

संपादित करें:

रेल के लिए 4 नोटेशन:

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

स्क्वाइल का उपयोग करते हुए रेल 4 में एक सबक्वायरी का उपयोग करके, यहां एक अधिक जटिल "इन नहीं" क्वेरी है। बेशक एसक्यूएल की तुलना में बहुत धीमी है, लेकिन हे, यह काम करता है।

    scope :translations_not_in_english, ->(calmapp_version_id, language_iso_code){
      join_to_cavs_tls_arr(calmapp_version_id).
      joins_to_tl_arr.
      where{ tl1.iso_code == 'en' }.
      where{ cavtl1.calmapp_version_id == my{calmapp_version_id}}.
      where{ dot_key_code << (Translation.
        join_to_cavs_tls_arr(calmapp_version_id).
        joins_to_tl_arr.    
        where{ tl1.iso_code == my{language_iso_code} }.
        select{ "dot_key_code" }.all)}
    }

दायरे में पहली 2 विधियां अन्य स्कॉप्स हैं जो उपनाम cavtl1 और tl1 घोषित करती हैं। << स्क्वायर में ऑपरेटर में नहीं है।

उम्मीद है कि यह किसी की मदद करता है।







activerecord