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.