如何从其中包含该类名称的字符串中调用一个类?(我想我可以做案件,但那看起来很丑。)
我问的原因是因为我正在使用acts_as_commentable
插件等,这些插件将commentable_type存储为一列。我希望能够调用任何特定的可注释类来对此进行find(commentable_id)
处理。
谢谢。
Answers:
我想你想要的是 constantize
这是一个RoR构造。我不知道有没有红宝石核
Module.const_get
。这样做的好处constantize
是,即使在深度嵌套的名称空间中也可以使用它,因此您可以'Functional::Collections::LazyList'.constantize
从Functional模块中的Collections模块中获取类LazyList,而对于const_get
,您必须执行'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get)
。
给定一个字符串,首先调用classify创建一个类名(仍然是一个字符串),然后调用constantize尝试查找并返回该类名常量(请注意,类名是constant)。
some_string.classify.constantize
我知道这是一个老问题,但是我只想留下这条笔记,这可能对其他人有帮助。
在普通的Ruby中,Module.const_get
可以找到嵌套常量。例如,具有以下结构:
module MyModule
module MySubmodule
class MyModel
end
end
end
您可以按以下方式使用它:
Module.const_get("MyModule::MySubmodule::MyModel")
MyModule.const_get("MySubmodule")
MyModule::MySubmodule.const_get("MyModel")
当ActiveSupport可用时(例如,在Rails中):String#constantize
或String#safe_constantize
,即"ClassName".constantize
。
在纯Ruby:中Module#const_get
,通常是Object.const_get("ClassName")
。
在最近的红宝石中,两者都使用嵌套在模块中的常量,例如in中Object.const_get("Outer::Inner")
。
如果要将字符串转换为实际的类名称以访问模型或任何其他类
str = "group class"
> str.camelize.constantize 'or'
> str.classify.constantize 'or'
> str.titleize.constantize
Example :
def call_me(str)
str.titleize.gsub(" ","").constantize.all
end
Call method : call_me("group class")
Result:
GroupClass Load (0.7ms) SELECT `group_classes`.* FROM `group_classes`