रूबी स्ट्रिंग में वर्ग नाम को वास्तविक कक्षा में परिवर्तित करता है


87

मैं एक स्ट्रिंग से एक वर्ग को कैसे बुलाऊंगा जिसमें उस वर्ग का नाम हो? (मुझे लगता है कि मैं केस कर सकता था / जब लेकिन वह बदसूरत लगता है।)

कारण मैं पूछ रहा हूँ क्योंकि मैं acts_as_commentableप्लगइन का उपयोग कर रहा हूँ , दूसरों के बीच, और ये एक स्तंभ के रूप में commentable_type संग्रहीत करते हैं। मैं उस पर जो भी विशेष टिप्पणी करने योग्य वर्ग कह सकता हूं, करने में सक्षम होना चाहता हूं find(commentable_id)

धन्यवाद।

जवाबों:


131

मुझे लगता है कि तुम क्या चाहते हो constantize

वह एक RoR निर्माण है। मुझे नहीं पता कि रूबी कोर के लिए एक है


बिल्कुल सही, बस यही मैं ढूंढ रहा था।
अवर्गीकृत

40
सादे रूबी के लिए, आप उपयोग करेंगे Module.const_get। इसका लाभ constantizeयह है कि यह गहरी नेस्टेड नेमस्पेस के साथ भी काम करता है, इसलिए आप कर सकते हैं 'Functional::Collections::LazyList'.constantizeऔर मॉड्यूल कलेक्शंस में मॉड्यूल कलेक्शंस से क्लास LazyList प्राप्त कर सकते हैं , जबकि const_get, आपको कुछ ऐसा करना होगा 'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get)
चक


34

एक स्ट्रिंग को देखते हुए, पहले कॉल को एक वर्ग नाम (अभी भी एक स्ट्रिंग) बनाने के लिए वर्गीकृत करें , फिर वर्ग नाम स्थिर (ध्यान दें कि वर्ग नाम स्थिरांक हैं ) को खोजने और वापस करने की कोशिश करने के लिए निरंतर कॉल करें ।

some_string.classify.constantize

10
आपको वर्गीकरण के बजाय ऊंटनी का उपयोग करना चाहिए क्योंकि वर्गीकरण तालिका नामों के लिए है और बहुवचन को अच्छी तरह से संभाल नहीं करता है।
पीटर ब्राउन

1
धन्यवाद! यह बहुत अच्छा है!
दुधो

2
आपका उत्तर वास्तव में मूल्यवान है, लेकिन आपको तालिका के नाम के लिए "शीर्षक" का उपयोग करना चाहिए जिसमें स्थान शामिल है, और अर्थ पूर्ण वर्ग का नाम बनाने के लिए स्ट्रिंग से सफेद स्थान हटा दें।
SSR

22

मुझे पता है कि यह एक पुराना प्रश्न है लेकिन मैं इस नोट को छोड़ना चाहता हूं, यह दूसरों के लिए मददगार हो सकता है।

सादे रूबी में, Module.const_getनेस्टेड स्थिरांक पा सकते हैं। उदाहरण के लिए, निम्नलिखित संरचना होना:

module MyModule
  module MySubmodule
    class MyModel
    end
  end
end

आप इसका उपयोग इस प्रकार कर सकते हैं:

Module.const_get("MyModule::MySubmodule::MyModel")
MyModule.const_get("MySubmodule")
MyModule::MySubmodule.const_get("MyModel")

7

जब ActiveSupport उपलब्ध है (जैसे रेल में): String#constantizeया String#safe_constantize, वह है "ClassName".constantize

शुद्ध रूबी में: Module#const_getआमतौर पर Object.const_get("ClassName")

हालिया माणिक में, दोनों कांस्टेंट के साथ काम करते हैं, जैसे मॉड्यूल में नेस्टेड Object.const_get("Outer::Inner")


6

यदि आप मॉडल या किसी अन्य वर्ग तक पहुँचने के लिए स्ट्रिंग को एक्चुअल क्लास नाम में बदलना चाहते हैं

str = "group class"

> str.camelize.constantize 'or'
> str.classify.constantize 'or'
> str.titleize.constantize

Example :
  def call_me(str)
    str.titleize.gsub(" ","").constantize.all
  end

Call method : call_me("group class")

Result:
  GroupClass Load (0.7ms) SELECT `group_classes`.* FROM `group_classes`
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.