Подтвердить что ты не робот

Как создать экземпляр класса из строки имени в 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", но он решает его цель.

4b9b3361

Ответ 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

Надеюсь, это окажется полезным. Спасибо!