2010-08-12 91 views
62

如何從包含該類名的字符串中調用類? (我想我可以做case /但是看起來很難看)ruby​​將字符串中的類名轉換爲實際類

我問的原因是因爲我使用acts_as_commentable插件等等,並且它們將commentable_type存儲爲列。我希望能夠調用任何特殊的可評論課程來對其做一個find(commentable_id)

謝謝。

回答

90

我想你想要的是constantize

這是一個RoR結構。我不知道如果有一對紅寶石核心

+0

完美,這正是我一直在尋找。 – unsorted 2010-08-12 01:12:54

+33

對於普通的Ruby,你可以使用'Module.const_get'。 'constantize'的優點在於它可以在深層嵌套的命名空間下工作,因此您可以執行'Functional :: Collections :: LazyList'.constantize'並從模塊Functional中的模塊集合中獲取LazyList類,而使用' const_get',你必須做一些像'Functional :: Collections :: LazyList'.split('::')。reduce(Module,:const_get)''。 – Chuck 2010-08-12 01:43:48

32
"Object".constantize # => Object 
+1

+1,因爲它是同時的 – unsorted 2010-08-12 01:13:19

25

給定一個字符串,第一個電話classify創建一個類名(仍然是一個字符串),然後調用constantize,試圖找到並返回類名常數(注意class names are constants)。

some_string.classify.constantize 
+6

你應該使用camelize而不是分類,因爲classify是用於表名,並且不能很好地處理複數。 – 2012-07-15 16:14:41

+1

謝謝!那很棒! – duykhoa 2013-03-26 09:15:55

+2

你的答案真的很有價值,但是你應該使用「titleize」作爲包含空格的表名,並且從字符串中刪除空格來表示完整的類名。 – SSR 2015-04-15 10:05:02

3

如果你想字符串轉換爲實際工作的類名來訪問模型或任何其他類

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` 
3

當的ActiveSupport是可用的(例如,在Rails的):String#constantizeString#safe_constantize,那就是"ClassName".constantize

在純Ruby中:Module#const_get,通常爲Object.const_get("ClassName")

在最近的紅寶石中,兩者都使用嵌套在模塊中的常量,如Object.const_get("Outer::Inner")

7

我知道這是一個古老的問題,但我只是想離開這個筆記,它可能對別人有幫助。

在純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")