Pass between string and class name

I have a string containing the name of the class. This is, for example, a string containing "Article". This line came from params []. What should I do to work with this string, as if it were a class name? For example, I want:

Article.all 

etc.

Any idea?

+1
string ruby class constants
Sep 19 '09 at 10:30
source share
3 answers

This solution is better than eval because you are evaluating a params hash that can manipulate the user and may contain harmful actions. Generally: Never evaluate a user’s input directly, this is a big security hole.

 # Monkey patch for String class class String def to_class klass = Kernel.const_get(self) klass.is_a?(Class) ? klass : nil rescue NameError nil end end # Examples "Fixnum".to_class #=> Fixnum "Something".to_class #=> nil 

Update is the best version that works with namespaces:

  # Monkey patch for String class class String def to_class chain = self.split "::" klass = Kernel chain.each do |klass_string| klass = klass.const_get klass_string end klass.is_a?(Class) ? klass : nil rescue NameError nil end end 
+4
Sep 19 '09 at 11:17
source share
 class Abc end #=> nil klass = eval("Abc") #=> Abc klass.new #=> #<Abc:0x37643e8> 

It is assumed that there is indeed a class with the specified name ...

ActiveSupport had String # constantize , which did the same, but I believe it is deprecated after 2.1.

EDIT: this is a constantization implementation from ActiveSupport 2.1.2:

  def constantize(camel_cased_word) names = camel_cased_word.split('::') names.shift if names.empty? || names.first.empty? constant = Object names.each do |name| constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name) end constant end 
+3
Sep 19 '09 at 10:38
source share

I'm not sure if I understand your intent correctly. Here I assume that all is a method of the Article class and all returns an array of articles.

 class Article def self.all ["Peopleware" , "The Mythical Man-Month"] end end s = "Article" all_of_article = [] eval("all_of_article = #{s + ".all"}") puts all_of_article.inspect # ["Peopleware", "The Mythical Man-Month"] 
0
Sep 19 '09 at 10:55
source share



All Articles