Como obtenho o nome de uma classe Ruby?


392

Como posso obter o nome da classe de um objeto ActiveRecord?

Eu tenho:

result = User.find(1)

Eu tentei:

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

Eu preciso apenas do nome da classe, em uma string ( Userneste caso). Existe um método para isso?

Sei que isso é bastante básico, mas procurei nos documentos do Rails e do Ruby e não consegui encontrá-lo.


11
@ Oliver N .: Com objetos Ruby normais, Object#class.inspectdá o mesmo que Object#class.name, embora esse não seja o caso com objetos ActiveRecord.
Andrew Grimm

Respostas:


732

Você deseja chamar .name na classe do objeto:

result.class.name

4
Quando eu fizer isso eu recebo os nomes módulo antes, então "Module :: Submódulo :: Class", há uma maneira de obter apenas "Classe"
Abe Petrillo

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

90
@Abe: clean cleaner (ActiveSupport):result.class.name.demodulize
pseidemann 30/10

2
Para os recém-chegados lá fora, você também pode obter o nome da classe como uma string usando a classe como este: User.name. User.to_stambém parece funcionar.
quer

O método demodulize vem daqui: apidock.com/rails/ActiveSupport/Inflector/demodulize (Você precisa carregar as inflexões de string do ActiveSupport para poder usar se, se você não for um projeto Rails.)
Por Lundberg

118

Aqui está a resposta correta, extraída dos comentários de Daniel Rikowski e pseidemann. Estou cansado de ter que procurar nos comentários para encontrar a resposta certa ...

Se você usa o Rails (ActiveSupport):

result.class.name.demodulize

Se você usa o POR (plain-ol-Ruby):

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

34

Ambos result.class.to_se result.class.nametrabalho.


34
Mas conceitualmente, #name retorna o nome, #to_s retorna uma representação de string, que por acaso é idêntica ao nome. Eu continuaria usando #name, apenas por retenção anal.
kch

7

Se você deseja obter um nome de classe de dentro de um método de classe, class.nameou self.class.namenão vai funcionar. Isso apenas produzirá Class, pois a classe de uma classe é Class. Em vez disso, você pode apenas usar name:

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

Foo::Bar.say_name

resultado:

I'm a Foo::Bar!

3

No meu caso, quando eu uso algo como result.class.nameeu tenho algo parecido Module1::class_name. Mas se apenas queremos class_name, use

result.class.table_name.singularize

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.