83

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

例如,我们在数据库中有它的名称,格式为“ClassName”或“my_super_class_name”。

我们如何从中创建对象?

解决方案:

自己找了,没找到,就在这里。 Ruby-on-Rails API 方法

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

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

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

当然,也许这不是非常“Rails 方式”,但它解决了它的目的。

4

4 回答 4

86
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
于 2012-12-28T13:41:31.103 回答
46

其他人也可能正在寻找一种在找不到类时不会引发错误的替代方法。safe_constantize就是这样。

class MyClass
end

"my_class".classify.safe_constantize.new #  #<MyClass:0x007fec3a96b8a0>
"omg_evil".classify.safe_constantize.new #  nil 
于 2015-03-06T23:53:38.273 回答
14

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

klass_name = "Module::ClassName"
klass_name.constantize

初始化一个新对象:

klass_name.constantize.new

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

于 2017-02-23T11:11:26.023 回答
6

我很惊讶没有人在他们的回应中考虑安全和黑客攻击。可能甚至间接来自用户输入的任意字符串的实例化是在自找麻烦和黑客攻击。除非我们确定字符串受到完全控制和监控,否则我们都应该/必须将其列入白名单

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

class_for(name_wherever_this_came_from).create!(params_somehow)

如何在没有白名单的情况下任意知道适当的参数将是一个挑战,但你明白了。

于 2016-11-18T16:25:44.140 回答