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.

et moi
la source
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
flicken
la source
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
Darren Hicks
la source
34

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

tal
la source
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!
jayhendren
la source
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

Chivorn Kouch
la source