ruby将字符串中的类名转换为实际类

uns*_*ted 84 ruby-on-rails

如何从包含该类名的字符串中调用类?(我想我可以做案例/什么时候,但这看起来很难看.)

我问的原因是因为我正在使用acts_as_commentable插件等,这些将commentable_type存储为列.我希望能够调用任何特定的可评论类来find(commentable_id)对其进行操作.

谢谢.

Jam*_*ong 124

我想你想要的是什么 constantize

这是一个RoR结构.我不知道是否有一个红宝石核心

  • 对于普通的Ruby,你可以使用`Module.const_get`.`constantize`的优点是它甚至可以使用深度嵌套的命名空间,因此你可以执行`'Functional :: Collections :: LazyList'.constantize`并从模块Functional中的模块Collections获取类LazyList,而使用` const_get`,你必须做类似`'Functional :: Collections :: LazyList'.split('::').reduce(Module,:const_get)`. (37认同)

jtb*_*des 43

"Object".constantize # => Object
Run Code Online (Sandbox Code Playgroud)


use*_*833 30

给定一个字符串,首先调用classify来创建一个类名(仍然是一个字符串),然后调用constantize来尝试查找并返回类名常量(注意类名是常量).

some_string.classify.constantize
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用camelize而不是classify,因为classify用于表名,并且不能很好地处理复数. (7认同)
  • 您的答案非常有价值,但您应该使用"titleize"表格名称,其中包括空格,并从字符串中删除空格以使其成为完整的班级名称. (2认同)

Edg*_*ega 18

我知道这是一个老问题,但我只是想留下这个说明,这可能对其他人有帮助.

在纯Ruby中,Module.const_get可以找到嵌套常量.例如,具有以下结构:

module MyModule
  module MySubmodule
    class MyModel
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式使用它:

Module.const_get("MyModule::MySubmodule::MyModel")
MyModule.const_get("MySubmodule")
MyModule::MySubmodule.const_get("MyModel")
Run Code Online (Sandbox Code Playgroud)


SSR*_*SSR 6

如果要将字符串转换为实际类名称以访问模型或任何其他类

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


ska*_*lee 5

当ActiveSupport可用时(例如在Rails中):String#constantize或者String#safe_constantize,即"ClassName".constantize.

在纯Ruby中:Module#const_get通常Object.const_get("ClassName").

在最近的rubies中,两者都使用嵌套在模块中的常量,例如Object.const_get("Outer::Inner").