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

Vja*_*its 68 string ruby-on-rails class instantiation ruby-on-rails-3

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

例如,我们在数据库中以"ClassName"或"my_super_class_name"的格式命名.

我们如何从中创建对象?

解:

正在寻找它,但没找到,所以在这里. Ruby-on-Rails API方法

name = "ClassName"
instance = name.constantize.new  
Run Code Online (Sandbox Code Playgroud)

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

name = "my_super_class"
instance = name.classify.constantize.new
Run Code Online (Sandbox Code Playgroud)

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

Eug*_*rke 73

klass = Object.const_get "ClassName"
Run Code Online (Sandbox Code Playgroud)

关于类方法

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
Run Code Online (Sandbox Code Playgroud)


man*_*ift 34

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

class MyClass
end

"my_class".classify.safe_constantize.new #  #<MyClass:0x007fec3a96b8a0>
"omg_evil".classify.safe_constantize.new #  nil 
Run Code Online (Sandbox Code Playgroud)


Rub*_*sMN 6

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

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

class_for(name_wherever_this_came_from).create!(params_somehow)
Run Code Online (Sandbox Code Playgroud)

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


Pus*_*abh 6

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

klass_name = "Module::ClassName"
klass_name.constantize
Run Code Online (Sandbox Code Playgroud)

要初始化一个新对象:

klass_name.constantize.new
Run Code Online (Sandbox Code Playgroud)

我希望这对您有所帮助。谢谢!

  • @TiSer 你能解释一下,只要我不常量化请求参数中的字符串,它就容易受到攻击吗? (2认同)