रेल 5: ActiveRecord या क्वेरी


109

आप Rails 5 ActiveRecord orमें क्वेरी कैसे करते हैं ? इसके अलावा, क्या ActiveRecord प्रश्नों के साथ चेन करना संभव है ?orwhere


जवाबों:


228

क्वेरी में orक्लॉज के साथ चेन क्लॉज की क्षमता रेल 5 में उपलब्ध होगी । देखें संबंधित चर्चा और पुल अनुरोधwhereActiveRecord

तो, आप निम्नलिखित चीजों को रेल 5 में कर पाएंगे :

एक प्राप्त करने के लिए postके साथ id1 या 2:

Post.where('id = 1').or(Post.where('id = 2'))

कुछ अन्य उदाहरण:

(A && B) || सी:

    Post.where(a).where(b).or(Post.where(c))

(ए: बी) और& सी:

    Post.where(a).or(Post.where(b)).where(c)

3
मैं कैसे प्राप्त कर सकता हूँ (A || B) && (C || D) मैंने Post.where (a) .or (Post.where (b)) की कोशिश की। जहाँ (c) .or (Post.where (d)) लेकिन यह इस प्रकार उत्पन्न होता है: (A || B) && C || D
इमरान अहमद

3
@ इमरान का मानना ​​है कि यह ऐसा होना Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))चाहिए (a a। B) && (c) d)
इंजीनियर्समैनी

1
@ इमरान यह मेरे लिए काम नहीं करता है: मुझे मिलता हैArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
सुआन

5
समतुल्य .or जो एक संबंध लेता है और एक .merge पैदा करता है। (ए (बी) और& (सी। डी।) पोस्ट। वे (ए) .ओर (पोस्ट.वे (बी)) के द्वारा उत्पादित किया जा सकता है। मर्ज (पोस्ट.वे। (सी) .or (पोस्ट। वे (डी) )))
Siim Liiser

2
@MathieuJ। यह ActiveRecord :: संबंध # मर्ज है। api.rubyonrails.org/classes/ActiveRecord/…
Siim Liiser

13

हमें इस ORक्वेरी का उपयोग करने के लिए रेल 5 की प्रतीक्षा करने की आवश्यकता नहीं है । हम इसके साथ भी उपयोग कर सकते हैं rails 4.2.3यहाँ एक बैकपोर्ट है

मणि के लिए एरिक-गुओ को धन्यवाद , जहां-या , अब हम इस मणि का उपयोग करके इस ORकार्यक्षमता को >= rails 4.2.3भी जोड़ सकते हैं ।


6

(केएम रकीबुल इस्लाम के जवाब के लिए एक अतिरिक्त)

स्कोप का उपयोग करते हुए, कोड प्रीटरियर बन सकता है (आंखों को देखने के आधार पर):

scope a,      -> { where(a) }
scope b,      -> { where(b) }

scope a_or_b, -> { a.or(b) }

5

मुझे ए करने की जरूरत थी (A && B) || (C && D) || (E && F)

लेकिन रेल 5.1.4की वर्तमान स्थिति में यह Arel या श्रृंखला के साथ पूरा करने के लिए बहुत जटिल है। लेकिन मैं अभी भी जितना संभव हो उतना क्वेरी उत्पन्न करने के लिए रेल का उपयोग करना चाहता था।

इसलिए मैंने एक छोटा हैक किया:

अपने मॉडल में मैंने एक निजी विधि बनाई, जिसे कहा जाता है sql_where:

private
  def self.sql_where(*args)
    sql = self.unscoped.where(*args).to_sql
    match = sql.match(/WHERE\s(.*)$/)
    "(#{match[1]})"
  end

अपने दायरे के आगे मैंने OR की पकड़ बनाने के लिए एक सरणी बनाई

scope :whatever, -> {
  ors = []

  ors << sql_where(A, B)
  ors << sql_where(C, D)
  ors << sql_where(E, F)

  # Now just combine the stumps:
  where(ors.join(' OR '))
}

जो अपेक्षित क्वेरी परिणाम का उत्पादन करेगा SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)):।

और अब मैं आसानी से किसी भी गलत OR के बिना अन्य scopes आदि के साथ इसे जोड़ सकता हूं।

सुंदरता यह है कि मेरा sql_where जहां-जहां सामान्य तर्क-वितर्क करता है: sql_where(name: 'John', role: 'admin')उत्पन्न करेगा (name = 'John' AND role = 'admin')


मुझे लगता है कि आप .merge&& के बराबर का उपयोग कर सकते हैं , और अपने परनों को पकड़ने के लिए एक उचित पेड़ का निर्माण कर सकते हैं । कुछ ऐसा ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF)), मान लें कि प्रत्येक स्कोप कुछ ऐसा दिखता हैModel.where(...)
nar8789

मर्ज का उपयोग करने से पहले इसे देखें - github.com/rails/rails/issues/33501
आरथी

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