Comment obtenir le nom d'une classe Ruby?


392

Comment puis-je obtenir le nom de classe à partir d'un objet ActiveRecord?

J'ai:

result = User.find(1)

J'ai essayé:

result.class
# => User(id: integer, name: string ...)
result.to_s
# => #<User:0x3d07cdc>"

Je n'ai besoin que du nom de classe, dans une chaîne ( Userdans ce cas). Y a-t-il une méthode pour cela?

Je sais que c'est assez basique, mais j'ai recherché les documents de Rails et Ruby, et je n'ai pas pu le trouver.


1
@Oliver N .: Avec les objets Ruby normaux, Object#class.inspectdonne la même chose que Object#class.name, alors que ce n'est pas le cas avec les objets ActiveRecord.
Andrew Grimm

Réponses:


732

Vous souhaitez appeler .name sur la classe de l'objet:

result.class.name

4
Quand je fais cela, j'obtiens les noms des modules avant, donc "Module :: SubModule :: Class", y a-t-il un moyen d'obtenir juste "Class"
Abe Petrillo

25
@Abe:result.class.name.split('::').last
Daniel Rikowski

90
@Abe: encore plus propre (ActiveSupport):result.class.name.demodulize
pseidemann

2
Pour les nouveaux venus là - bas, vous pouvez également obtenir le nom de la classe comme une chaîne en utilisant la classe comme ceci: User.name. User.to_ssemble également fonctionner.
Dan Polites

La méthode de démodulation vient d'ici: apidock.com/rails/ActiveSupport/Inflector/demodulize (Vous devez charger les inflexions de chaîne ActiveSupport pour pouvoir les utiliser si, si vous n'êtes pas un projet Rails.)
Par Lundberg

118

Voici la bonne réponse, extraite des commentaires de Daniel Rikowski et pseidemann. J'en ai assez de devoir parcourir les commentaires pour trouver la bonne réponse ...

Si vous utilisez Rails (ActiveSupport):

result.class.name.demodulize

Si vous utilisez POR (plain-ol-Ruby):

result.class.name.split('::').last

34

Les deux result.class.to_set le result.class.nametravail.


34
Mais conceptuellement, #name renvoie le nom, #to_s renvoie une représentation sous forme de chaîne, qui se trouve être identique au nom. Je m'en tiendrai à l'utilisation de #name, juste par rétention anale.
kch

7

Si vous souhaitez obtenir un nom de classe à l'intérieur d'une méthode de classe, class.nameou self.class.namene fonctionnera pas. Ceux-ci ne feront que sortir Class, puisque la classe d'une classe l'est Class. Au lieu de cela, vous pouvez simplement utiliser name:

module Foo
  class Bar
    def self.say_name
      puts "I'm a #{name}!"
    end
  end
end

Foo::Bar.say_name

production:

I'm a Foo::Bar!

3

Dans mon cas, lorsque j'utilise quelque chose comme, result.class.namej'ai quelque chose comme Module1::class_name. Mais si nous voulons seulement class_name, utilisez

result.class.table_name.singularize

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.