2010-03-23 11 views
10

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

जो प्रश्न मैं पूछ रहा हूं वह एक व्यापक है, लेकिन मेरे विशेष मामले में, मैं अपने पोस्टग्रेज़ डेटाबेस में एक कॉलम के साथ काम कर रहा हूं, जहां तक ​​मुझे पता नहीं है कि रेलवे स्पष्ट रूप से समझ में नहीं आता है, जो कि सादेदार है पाठ खोज जानकारी। रेल इसे लिखने और पढ़ने में सक्षम हैं जैसे कि यह एक स्ट्रिंग है, हालांकि, एक स्ट्रिंग के विपरीत, यह स्वचालित रूप से तब से बच नहीं रहा है जब मैं मॉडल के अंदर वेक्टर = चीजें करता हूं।

उदाहरण के लिए, जब मैं model.name = '::' करता हूं, जहां नाम एक स्ट्रिंग है, तो यह ठीक काम करता है। जब मैं model.vector = '::' यह त्रुटियों कार्य करें:

ActiveRecord::StatementInvalid: PGError: ERROR: syntax error in tsvector: "::" 
"vectors" = E'::' WHERE "id" = 1 

यह अर्धविराम के बचने की कमी के कारण एक समस्या लगती है, और मैं मैन्युअल वेक्टर = '::' ठीक सेट कर सकते हैं ।

मैं भी उज्जवल विचार था शायद मैं सिर्फ तरह कुछ कॉल कर सकते हैं:,

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::" 

हालांकि, इस वाक्य रचना काम नहीं करता है क्योंकि कच्चे SQL कमांड का पता लगाने के लिए भागने की विधि पहुँच नहीं है और स्ट्रिंग का उपयोग करके स्ट्रिंग इनपुट? निशान।

यह मुझे किसी भी प्रकार के उपयोगकर्ता इनपुट के साथ कनेक्शन.execute को कॉल करने के समान समस्या के रूप में हमला करता है, क्योंकि यह सभी तारों को स्वच्छ करने के लिए उबलता है, लेकिन मुझे रेल की SQL स्ट्रिंग को मैन्युअल रूप से कॉल करने का कोई तरीका नहीं दिख रहा है स्वच्छता विधियों। क्या कोई सलाह दे सकता है?

उत्तर

14

अपने मॉडल के लिए इस विधि जोड़ें:

class Media < ActiveRecord::Base 
    def self.execute_sql(*sql_array)  
    connection.execute(send(:sanitize_sql_array, sql_array)) 
    end 
end 

अब आप इस तरह के रूप में किसी भी एसक्यूएल निष्पादित कर सकते हैं:

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::') 

संदर्भ

1) sanitize_sql_array

+1

टिप के लिए धन्यवाद, जैसा आपने कहा था ठीक उसी तरह काम किया। दुर्भाग्यवश, हालांकि, ऐसा लगता है कि रेल वास्तव में एसक्यूएल के लिए कॉलन (:) वास्तव में sanitize नहीं है, और मुझे अभी भी उस रेखा पर त्रुटियां मिल रही हैं। शायद कोलों को स्वच्छ करने की आवश्यकता होती है, यह तवेदकों के लिए अद्वितीय है। ऐसा लगता है कि मुझे क्रैकी रेगेक्स मार्ग पर जाना होगा। –