2011-07-21 20 views
11

तो मेरी समस्या यहां है।डेटाबेस से स्ट्रिंग में रेल स्ट्रिंग इंटरपोलेशन

मैं मॉडल में संग्रहीत एक स्ट्रिंग को पुनर्प्राप्त करना चाहता हूं और रनटाइम पर रेल अनुप्रयोग से एक चर का उपयोग करके इसका एक हिस्सा बदलना चाहता हूं। यहां एक उदाहरण दिया गया है:

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

"Hi #{user.name}, ...." 

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

अग्रिम धन्यवाद।

उत्तर

9

यदि आप चाहते हैं

"Hi #{user.name}, ...." 
अपने डेटाबेस में

, एकल उद्धरण का उपयोग करें या एक बैकस्लैश के साथ # बचने #{} सामान interpolating अभी से रूबी रखने के लिए:

s = 'Hi #{user.name}, ....' 
s = "Hi \#{user.name}, ...." 

फिर, बाद में जब यदि आप साहसी या भरोसेमंद थे, तो आप इंटरपोलेशन करना चाहते हैं, eval:

s = pull_the_string_from_the_database 
msg = eval '"' + s + '"' 
का उपयोग करें

ध्यान दें कि के लिए काम करने के लिए आपको s को डबल उद्धृत स्ट्रिंग में बदलना होगा। यह काम करेगा लेकिन यह सबसे अच्छा दृष्टिकोण नहीं है और आप सभी तरह के अजीब और भ्रमित त्रुटियों के लिए खुलते हैं लेकिन यह ठीक होना चाहिए जब तक आप (या अन्य भरोसेमंद लोग) तार लिख रहे हों; मुझे लगता है कि आप एक सरल सूक्ष्म templating प्रणाली, यहां तक ​​कि इस के रूप में सरल कुछ के साथ बेहतर होगा:

def fill_in(template, data) 
    template.gsub(/\{\{(\w+)\}\}/) { data[$1.to_sym] } 
end 
#... 
fill_in('Hi {{user_name}}, ....', :user_name => 'Pancakes') 

आप इस्तेमाल कर सकते हैं जो कुछ भी सीमांकक आप निश्चित रूप से चाहता था, मैं क्योंकि मैं प्रयोग कर रहे {{...}} साथ चला गया Mustache.js और Handlebars.js हाल ही में। इस निष्पक्ष कार्यान्वयन में समस्याएं हैं (कोई टेम्पलेट स्वरूपण विकल्प नहीं, कोई डेलीमीटर बचाना नहीं है ...) लेकिन यह पर्याप्त हो सकता है; यदि आपके टेम्पलेट्स अधिक जटिल हो जाते हैं तो आप डेटाबेस में ERB की बिट्स स्टोर करना चाहते हैं और इसके साथ मानक लाइब्रेरी सौदे में ईआरबी प्रोसेसर का उपयोग करना चाहते हैं।

+0

धन्यवाद, यह काम किया ... मैं पहले से ही एकल उद्धृत स्ट्रिंग संग्रहित कर रहा था। मैं बस डेटाबेस से प्राप्त करने के बाद interpolate कैसे लापता था। मुझे इसका उपयोग करने के आसपास सुरक्षा जोखिम से अवगत है, लेकिन उपयोगकर्ता सीधे इस स्ट्रिंग को नहीं बदल सकते हैं। –

+0

मैं जोड़ूंगा कि अगर आपकी स्ट्रिंग में एचटीएमएल में 'raw' (http://apidock.com/rails/ActionView/Helpers/OutputSafetyHelper/raw) विधि 'html_safe' विधि बनाम विधि का उपयोग किया गया है। – dennismonsewicz

0

एक तरह से मैं यह कर के बारे में सोच सकता है, उदाहरण के लिए भंडारित किया टेम्पलेट्स के लिए है:

"हाय नाम"

तो मॉडल में एक समारोह है कि बस से पारित कर दिया साथ टेम्पलेट टैग (नाम) की जगह है तर्क। यह उपयोगकर्ता भी लॉग इन हो सकता है।

क्योंकि यह नया फ़ंक्शन मॉडल का हिस्सा होगा, आप इसका उपयोग HTML.erb फ़ाइल सहित रेल में कहीं से भी मॉडल के किसी अन्य क्षेत्र की तरह कर सकते हैं।

आशा है कि मदद करता है, अगर आपको अधिक विवरण की आवश्यकता है तो मुझे बताएं।

+0

मैं हो यह, मुझे लगता है कि यह काम करेगा, समस्या मैं इस में देखते हैं कि मैं हर संभव टैग को परिभाषित करने के लिए होगा मैं का उपयोग करें और प्रत्येक मैप कर सकते है आवेदन के अंदर संबंधित चर/कार्यों में से एक। बस सोचा कि ऐसा करने का एक आसान तरीका होगा, जैसे सामान्य स्ट्रिंग के लिए इंटरपोलेशन। –

+0

मुझे लगता है कि आपका दृष्टिकोण भी काम करना चाहिए। डबल स्ट्रॉट्स के बजाय सिंगल कोट्स का उपयोग करके स्ट्रिंग बनाकर डेटाबेस में संग्रहीत होने से पहले आप स्ट्रिंग से बचने वाली स्ट्रिंग से बच सकते हैं। मुझे यकीन नहीं है कि यह देखने से पहले क्यों बच निकला है। – Shaunak

+0

मैं एकल उद्धृत संस्करण संग्रहित कर रहा था, लेकिन यह डेटाबेस में सहेजने से पहले एक बच निकले डबल उद्धृत स्ट्रिंग में बदल जाता है। –

34

मुझे कस्टम स्ट्रिंग सहायक कार्यों को परिभाषित करने का कोई कारण नहीं दिख रहा है। रुबी very nice formatting approaches प्रदान करता है, उदा।:

"Hello %s" % ['world'] 

या

"Hello %{subject}" % { subject: 'world' } 

दोनों उदाहरण "हैलो दुनिया" वापस जाएँ।

+5

यह समस्या है – januszm

+1

समस्या के लिए सबसे सुंदर और सरल समाधान imho है। मौजूदा कार्यक्षमता का उपयोग करके यह सबसे आसान समाधान है। – CDub

0

जोड़ा जा रहा है एक और संभव समाधान Procs का उपयोग कर:

#String can be stored in the database 
string = "->(user){ 'Hello ' + user.name}" 

proc = eval(string) 

proc.call(User.find(1)) #=> "Hello Bob" 
संबंधित मुद्दे