2011-03-16 15 views
19

मैं रेल 3.xरेल 2.x और 3.x में ActiveRecord के साथ "पसंद" प्रश्न करें?

Speaker.where("name like '%yson%'") 

में इस तरह के प्रश्नों कर रहा हूँ, लेकिन मैं डीबी विशिष्ट कोड से बचने के लिए अच्छा लगेगा। ऐसा करने का सही तरीका क्या है?

यदि रेल 2x में ऐसा करने का कोई तरीका है, तो इससे भी मदद मिलेगी।

उत्तर

11

आप इसके लिए .matches का उपयोग कर सकते हैं।

> t[:name].matches('%lore').to_sql 
=> "\"products\".\"name\" LIKE '%lore'" 

एक प्रश्न में वास्तविक उपयोग होगा:

Speaker.where(Speaker.arel_table[:name].matches('%lore')) 
+0

बुरा नहीं है। मुझे लगता है कि SQLite, Postgres और MySQL के बीच प्रतिशत संकेत सामान्य हो सकता है। –

+1

पढ़ने के लिए कोड स्निपेट को संशोधित करने का सुझाव दें: 'अध्यक्ष। कहीं (अध्यक्ष .arel_table [: name] .matches ('% yson% ')) ' –

2

कॉलर के लिए इंडेक्स बनाने के लिए सोलर या स्फिंक्स जैसे खोज इंजन का उपयोग करें, जो आप जैसे क्वेरी कर रहे हैं। की तरह प्रश्नों को हमेशा एक पूर्ण तालिका स्कैन में परिणाम मिलता है जब आप व्याख्या योजना को देखते हैं तो आपको वास्तव में उन्हें किसी उत्पादन साइट में कभी भी उपयोग नहीं करना चाहिए।

+1

मैंने इसे वोट दिया, लेकिन "वास्तव में उनका उपयोग कभी नहीं करना चाहिए" थोड़ा मजबूत है। यदि आपके पास रिकॉर्ड्स की मिडलिंग संख्या है, तो मैं मध्य स्तर पर पुनर्प्राप्त करने और पुन: प्रयास करने के बजाय एक समान क्वेरी का उपयोग करना पसंद करूंगा। जाहिर है यदि प्रदर्शन एक समस्या हो जाता है, तो आपको एक अनुक्रमणिका का उपयोग करना चाहिए। मुझे लगता है कि आपका मतलब "या" नहीं "," बीटीडब्ल्यू। –

1
नहीं रेल में डिफ़ॉल्ट रूप से

, के बाद से वहाँ, इतने सारे डीबी विकल्प (MySQL, PostgreSQL, MongoDB, CouchDB ...) कर रहे हैं आप, लेकिन MetaWhere, जहाँ आप की तरह कर सकते हैं की तरह जवाहरात की जाँच कर सकते हैं:

Article.where(:title.matches => 'Hello%', :created_at.gt => 3.days.ago) 
    => SELECT "articles".* FROM "articles" WHERE ("articles"."title" LIKE 'Hello%') 
    AND ("articles"."created_at" > '2010-04-12 18:39:32.592087') 

सामान्य में हालांकि आप शायद, कुछ डीबी विशिष्ट कोड होना चाहिए या अपने कोड refactor करेंगे (यानी फिर से परिभाषित रों पर .matches ऑपरेटर मेटावेयर में ymbols) एक अलग डेटाबेस के साथ काम करने के लिए। उम्मीद है कि आप अक्सर अपने डेटाबेस को नहीं बदलेंगे, लेकिन यदि आपके पास एक केंद्रीकृत स्थान होना चाहिए जहां आप इन ऑपरेटरों को फिर से उपयोग के लिए परिभाषित करते हैं। ध्यान रखें कि एक डेटाबेस में परिभाषित ऑपरेटर या फ़ंक्शन किसी अन्य में उपलब्ध नहीं हो सकता है, इस मामले में यह सामान्यीकृत ऑपरेशन चल रहा है क्योंकि आप वैसे भी खोज निष्पादित नहीं कर पाएंगे।

+0

धन्यवाद। यह डीबी को बदलने के बारे में कभी नहीं है: यह मध्यम स्तर को डीबी-विशिष्ट कोड से भरा नहीं है, इसलिए आप इसे काट और पेस्ट कर सकते हैं, और आम तौर पर भूल जाते हैं कि डीबी मौजूद है। –

+0

तब मुझे लगता है कि मेटावेयर मणि आपकी सबसे अच्छी शर्त है। यह इस तरह से सार तत्व बनाता है और आपको 'शीर्षक LIKE' के बजाय शीर्षक वाक्यमैट जैसे शांत वाक्यविन्यास का उपयोग करने देता है। –

+0

धन्यवाद जल्द ही इसे देखने की उम्मीद है –

23

रेल 3 में या अधिक से अधिक

Speaker.where("name LIKE ?", "%yson%") 

रेल में 2

Speaker.all(:conditions => ["name LIKE ?", "%yson%"]) 

बचें सीधे तार को जोड़ सकता है क्योंकि मूल्य का उपयोग नहीं किया जाएगा और आप एसक्यूएल इंजेक्शन हमले के लिए असुरक्षित है।

+1

शांत और सही हालांकि यह प्रश्न का उत्तर नहीं देता है। –

संबंधित मुद्दे