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

在 Ruby-on-Rails 我们如何从它的名字字符串实例化 class?

例如,我们在数据库中以“ ClassName”或“ my _ super _ class _ name”的格式显示它的名称。

我们如何从中创建对象?

解决方案:

我自己也在找,但没找到,所以就找到了。 Ruby-on-Rails API 方法

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

它甚至可以不格式化,我们可以用字符串方法 。分类

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

当然,这可能不是很“ Rails 的方式”,但它解决了它的目的。

45877 次浏览
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

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

class MyClass
end


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

我很惊讶竟然没人考虑安全和黑客攻击。任意字符串的实例化可能甚至间接来自于用户输入,这是自找麻烦和自找麻烦。我们都应该/必须列出白名单,除非我们确信字符串是完全受控和监视的

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


class_for(name_wherever_this_came_from).create!(params_somehow)

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

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

klass_name = "Module::ClassName"
klass_name.constantize

初始化新对象:

klass_name.constantize.new

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