Как создать экземпляр класса из строки имени в Rails?
Как мы можем создать экземпляр класса из его строки имени в Ruby-on-Rails?
Например, у нас есть это имя в базе данных в формате "ClassName" или "my_super_class_name".
Как мы можем создать объект из него?
Решение:
Искал его сам, но не нашел, так вот он.
API-интерфейс Ruby-on-Rails
name = "ClassName"
instance = name.constantize.new
Он может быть даже не отформатирован, мы можем использовать метод пользовательской строки .classify
name = "my_super_class"
instance = name.classify.constantize.new
Конечно, возможно, это не очень "путь Rails", но он решает его цель.
Ответы
Ответ 1
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
Ответ 2
Другие могут также искать альтернативу, которая не выдает ошибки, если не сможет найти класс. safe_constantize
- это просто.
class MyClass
end
"my_class".classify.safe_constantize.new # #<MyClass:0x007fec3a96b8a0>
"omg_evil".classify.safe_constantize.new # nil
Ответ 3
Я удивлен, что никто не рассматривает безопасность и взлом в своих ответах. Игнорирование произвольной строки, которая, скорее всего, косвенно поступает с пользовательского ввода, вызывает проблемы и взлом. Мы все должны/должны быть whitelisting, если мы не уверены, что строка полностью контролируется и контролируется
def class_for(name)
{
"foo" => Foo,
"bar" => Bar,
}[name] || raise UnknownClass
end
class_for(name_wherever_this_came_from).create!(params_somehow)
Как бы вы знали подходящие параметры произвольно, не имея белого списка, было бы сложным, но вы поняли идею.
Ответ 4
Вы можете просто преобразовать строку и инициализировать класс из нее:
klass_name = "Module::ClassName"
klass_name.constantize
Чтобы инициализировать новый объект:
klass_name.constantize.new
Надеюсь, это окажется полезным.
Спасибо!