如何从ActiveRecord对象中获得类名?
我有:
result = User.find(1)
我试着:
result.class
# => User(id: integer, name: string ...)
result.to_s
# => #<User:0x3d07cdc>"
我只需要类名,在字符串中(在本例中为User)。有什么方法吗?
我知道这是非常基本的,但是我搜索了Rails和Ruby的文档,我没有找到它。
如何从ActiveRecord对象中获得类名?
我有:
result = User.find(1)
我试着:
result.class
# => User(id: integer, name: string ...)
result.to_s
# => #<User:0x3d07cdc>"
我只需要类名,在字符串中(在本例中为User)。有什么方法吗?
我知道这是非常基本的,但是我搜索了Rails和Ruby的文档,我没有找到它。
以下是正确答案,摘自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.name或self.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中,正如其他人提到的,您可以对字符串使用解调方法,该方法由Active Support添加。它从字符串中的常量表达式中删除模块部分。
irb(main):014:0> account.class.name.demodulize
=> "Account"
在内部,该方法调用ActiveSupport::Inflector类上的解调类方法,并将自身作为参数传递。
# 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函数获得::最后一次出现的索引。如果它存在,则返回剩余的子字符串。否则,返回原始字符串。数组(n . .表达式返回从n到字符串的最后一个字符的子字符串。
现在我还没有做任何基准测试研究,以找出为什么Rails使用rindex这种替代方法(如果您知道原因,请评论),但是作为一个代码可读性爱好者,我喜欢第一个使用split和最后一个函数的方法。
来源:如何在Rails中获取对象的类名