如何获得Ruby类的名称?

如何从ActiveRecord对象中获得类名?

我有:

result = User.find(1)

我试着:

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

我只需要类名,在字符串中(在本例中为User)。有什么方法吗?

我知道这是非常基本的,但是我搜索了Rails和Ruby的文档,我没有找到它。

316254 次浏览

你想在对象的类上调用. name:

result.class.name

result.class.to_sresult.class.name都可以工作。

以下是正确答案,摘自Daniel Rikowski和pseidemann的评论。我厌倦了在评论中寻找正确答案。

如果你使用Rails (ActiveSupport):

result.class.name.demodulize

如果你使用POR (plain-ol-Ruby):

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

在我的情况下,当我使用类似result.class.name的东西时,我得到了类似Module1::class_name的东西。但如果我们只想要class_name,则使用

result.class.table_name.singularize

如果你想从类方法内部获取类名,class.nameself.class.name将不起作用。它们只会输出Class,因为类的类是Class。相反,你可以使用name:

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


Foo::Bar.say_name

输出:

I'm a Foo::Bar!

在Ruby中,你可以像下面这样使用object.class.name方法。

module Bank
class Account
end
end


irb(main):005:0> account = Bank::Account.new
=> #<Bank::Account:0x0000000106115b00>
irb(main):006:0> account.class.name
=> "Bank::Account"
irb(main):008:0> account.class.name.split("::").last
=> "Account"

在Rails中,正如其他人提到的,你可以对一个字符串使用demodulize方法,它是由活动支持添加的。它从字符串中的常量表达式中删除模块部分。

irb(main):014:0> account.class.name.demodulize
=> "Account"

在内部,该方法调用ActiveSupport::Inflector类上的demodulize类方法,并将自身作为参数传递。

# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 166
def demodulize
ActiveSupport::Inflector.demodulize(self)
end

Inflector.demodulize函数做同样的事情。

demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections"
demodulize('Inflections')                           # => "Inflections"
demodulize('::Inflections')                         # => "Inflections"
demodulize('')                                      # => ""

但是,它的内部实现与上面的简单版本不同。

# File activesupport/lib/active_support/inflector/methods.rb, line 228
def demodulize(path)
path = path.to_s
if i = path.rindex("::")
path[(i + 2)..-1]
else
path
end
end

在将path参数转换为字符串后,它使用Ruby的rindex函数获取::最后一次出现的索引。如果它存在,则返回剩余的子字符串。否则,返回原始字符串。array[n..-1]表达式返回从n到字符串最后一个字符的子字符串。

现在我还没有做任何基准测试研究,以找出为什么Rails使用rindex来使用这种替代方法(如果你知道原因,请评论),但作为一个代码可读性爱好者,我喜欢使用splitlast函数的第一个方法。

来源:如何在Rails中获得一个对象的类名