如何在Rails中从名称字符串实例化类?

时间:2012-12-28 13:36:48

标签: ruby-on-rails ruby-on-rails-3 string class instantiation

我们如何在Ruby-on-Rails中使用它的名称字符串实例化类?

例如,我们在数据库中以“ClassName”或“my_super_class_name”等格式命名。

我们如何从中创建对象?

解决方案:

我自己在找,但没有找到,所以在这里。 Ruby-on-Rails API Method

name = "ClassName"
instance = name.constantize.new  

它甚至可以不格式化,我们可以用户字符串方法 .classify

name = "my_super_class"
instance = name.classify.constantize.new

当然也许这不是'Rails方式',但它解决了它的目的。

4 个答案:

答案 0 :(得分:70)

klass = Object.const_get "ClassName"

关于类方法

class KlassExample
    def self.klass_method
        puts "Hello World from Class method"
    end
end
klass = Object.const_get "KlassExample"
klass.klass_method

irb(main):061:0> klass.klass_method
Hello World from Class method

答案 1 :(得分:33)

其他人也可能正在寻找一种替代方案,如果找不到类,就不会抛出错误。 safe_constantize就是这样。

class MyClass
end

"my_class".classify.safe_constantize.new #  #<MyClass:0x007fec3a96b8a0>
"omg_evil".classify.safe_constantize.new #  nil 

答案 2 :(得分:5)

您可以简单地转换字符串并通过以下方式初始化类:

klass_name = "Module::ClassName"
klass_name.constantize

初始化新对象:

klass_name.constantize.new

我希望这会有所帮助。 谢谢!

答案 3 :(得分:3)

我很惊讶没有人在考虑安全和黑客的反应。任意字符串的实例化甚至可能间接来自用户输入,这就是要求麻烦和黑客攻击。我们都应该/必须是白名单,除非我们确定字符串是完全受控和监控的

def class_for(name)
  {
    "foo" => Foo,
    "bar" => Bar,
  }[name] || raise UnknownClass
end

class_for(name_wherever_this_came_from).create!(params_somehow)

如果没有白名单,你如何随意地知道适当的参数会很有挑战性,但你明白了。