ruby dizedeki sınıf adını gerçek sınıfa dönüştür


88

İçinde o sınıf adını içeren bir dizeden bir sınıfı nasıl çağırırım? (Sanırım durum / ne zaman yapabilirim ama bu çirkin görünüyor.)

Sormamın nedeni acts_as_commentable, diğerlerinin yanı sıra eklentiyi kullanıyorum ve bunlar commentable_type'ı bir sütun olarak saklıyor. find(commentable_id)Üzerine yorum yapmak için herhangi bir özel yorumlanabilir sınıfı arayabilmek istiyorum .

Teşekkürler.

Yanıtlar:


132

Bence senin istediğin constantize

Bu bir RoR yapısı. Ruby çekirdeği için bir tane var mı bilmiyorum


mükemmel, tam da aradığım buydu.
sıralanmamış

40
Sade Ruby için kullanırsınız Module.const_get. Bunun avantajı, constantizederinlemesine iç içe geçmiş ad alanlarıyla bile çalışmasıdır, böylece 'Functional::Collections::LazyList'.constantizeLazyList sınıfını Functional modülündeki Collections modülünden alabilir ve alabilirsiniz, oysa bunun const_getgibi bir şey yapmanız gerekir 'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get).
Chuck

46
"Object".constantize # => Object

Lütfen bunun .constantizebir Rails yöntemi olduğunu unutmayın, onu düz Ruby'de bulamazsınız
Edgar Ortega

35

Bir dize, ilk çağrı alındığında sınıflandırır bir sınıf adı (hala bir dize) oluşturmak için, o çağrı constantize bulmak ve sınıf adı sabiti (yani not dönmek için denemek için sınıf isimleri sabitlerdir ).

some_string.classify.constantize

10
Classify tablo adları için olduğundan ve çoğullaştırmayı çok iyi ele almadığından, classify yerine camelize kullanmalısınız.
Peter Brown

2
Cevabınız gerçekten değerlidir, ancak boşluğa göre içeren tablo adı için "titleize" kullanmalı ve tam sınıf adını anlamlandırmak için dizeden beyaz boşluğu kaldırmalısınız.
SSR

22

Bunun eski bir soru olduğunu biliyorum ama sadece bu notu bırakmak istiyorum, başkaları için faydalı olabilir.

Düz Ruby'de Module.const_getyuvalanmış sabitleri bulabilir. Örneğin, aşağıdaki yapıya sahip olmak:

module MyModule
  module MySubmodule
    class MyModel
    end
  end
end

Aşağıdaki gibi kullanabilirsiniz:

Module.const_get("MyModule::MySubmodule::MyModel")
MyModule.const_get("MySubmodule")
MyModule::MySubmodule.const_get("MyModel")

7

ActiveSupport mevcut olduğunda (örn. Rails'te): String#constantizeveya String#safe_constantize, yani "ClassName".constantize.

Saf Ruby'de: Module#const_gettipik olarak Object.const_get("ClassName").

Son Ruby'lerde, her ikisi de içindeki gibi modüllerin içine yerleştirilmiş sabitlerle çalışır Object.const_get("Outer::Inner").


6

Dizeyi modele veya başka bir sınıfa erişmek için actuall sınıf adına dönüştürmek istiyorsanız

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`
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.