web-dev-qa-db-ja.com

Railsの名前文字列からクラスをインスタンス化する方法は?

Ruby-on-Railsの名前文字列からクラスをインスタンス化する方法は?

たとえば、データベースに「ClassName」や「my_super_class_name」などの形式で名前があります。

それからオブジェクトを作成する方法は?

解決策:

自分で探していましたが、見つかりませんでしたので、ここにあります。 Ruby-on-Rails APIメソッド

name = "ClassName"
instance = name.constantize.new  

フォーマットすることさえできません。文字列メソッド。classifyを使用できます。

name = "my_super_class"
instance = name.classify.constantize.new

もちろん、これは多分「レールウェイ」ではないかもしれませんが、それはその目的を解決します。

67
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
71
Eugene Rourke

また、クラスを見つけられなかった場合にエラーをスローしない代替手段を探しているかもしれません。 safe_constantizeはそれだけです。

class MyClass
end

"my_class".classify.safe_constantize.new #  #<MyClass:0x007fec3a96b8a0>
"omg_evil".classify.safe_constantize.new #  nil 
33
maninalift

次の方法で、単純に文字列を変換し、そこからクラスを初期化できます。

klass_name = "Module::ClassName"
klass_name.constantize

新しいオブジェクトを初期化するには:

klass_name.constantize.new

これがお役に立てば幸いです。ありがとう!

6

応答でセキュリティとハッキングを検討している人がいないことに驚いています。ユーザー入力から間接的にでも来る可能性が高い任意の文字列のインスタンス化は、トラブルとハッキングを求めています。文字列が完全に制御および監視されていることが確実でない限り、全員がホワイトリストに登録する必要があります。

def class_for(name)
  {
    "foo" => Foo,
    "bar" => Bar,
  }[name] || raise UnknownClass
end

class_for(name_wherever_this_came_from).create!(params_somehow)

ホワイトリストを作成せずに適切なパラメーターを任意に知る方法は困難ですが、アイデアは得られます。

3
RubesMN