루비 문자열의 클래스 이름을 실제 클래스로 변환


87

클래스 이름이 포함 된 문자열에서 클래스를 호출하려면 어떻게해야합니까? (나는 사건 / 언제를 할 수 있다고 생각하지만 그것은 추악한 것 같습니다.)

내가 묻는 이유는 acts_as_commentable다른 것들 중에서 플러그인을 사용하고 있기 때문에 commentable_type을 열로 저장하기 때문입니다. 나는 find(commentable_id)그것에 대해 할 수있는 특정 주석 클래스를 호출 할 수 있기를 원합니다 .

감사.

답변:


131

나는 당신이 원하는 것은 constantize

그것은 RoR 구조입니다. 루비 코어가 있는지 모르겠어요


완벽합니다. 그게 제가 찾던 것입니다.
분류되지

40
일반 Ruby의 경우 Module.const_get. 의 장점은 constantize당신이 할 수 있도록이, 심지어 깊이 중첩 된 네임 스페이스와 함께 작동한다는 것입니다 'Functional::Collections::LazyList'.constantize및 기능 모듈의 모듈 컬렉션에서 클래스 LazyList를 얻을 수와 반면에 const_get, 당신이 뭔가를해야 할 것입니다 'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get).


35

문자열이 주어지면 먼저 classify 를 호출 하여 클래스 이름 (여전히 문자열)을 만든 다음 constantize 를 호출 하여 클래스 이름 상수를 찾아 반환합니다 ( 클래스 이름은 상수입니다 ).

some_string.classify.constantize

10
classify는 테이블 이름을위한 것이고 복수형을 잘 처리하지 않기 때문에 classify 대신 camelize를 사용해야합니다.
Peter Brown

1
감사! 훌륭합니다!
duykhoa 2013 년

2
당신의 대답은 정말 가치가 있지만, 공백으로 포함하는 테이블 이름에 "titleize"를 사용하고 전체 클래스 이름을 의미하기 위해 문자열에서 공백을 제거해야합니다.
SSR 2015

22

나는 이것이 오래된 질문이라는 것을 알고 있지만이 메모를 남기고 싶습니다. 다른 사람들에게 도움이 될 수 있습니다.

일반 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")


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`
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.