Làm thế nào để tôi có được tên của một lớp Ruby?


392

Làm cách nào tôi có thể nhận được tên lớp từ một đối tượng ActiveRecord?

Tôi có:

result = User.find(1)

Tôi đã thử:

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

Tôi chỉ cần tên lớp, trong một chuỗi ( Usertrong trường hợp này). Có một phương pháp cho điều đó?

Tôi biết điều này khá cơ bản, nhưng tôi đã tìm kiếm cả tài liệu của Rails và Ruby, và tôi không thể tìm thấy nó.


1
@Oliver N.: Với các đối tượng Ruby bình thường, Object#class.inspectcung cấp tương tự Object#class.name, trong khi đây không phải là trường hợp với các đối tượng ActiveRecord.
Andrew Grimm

Câu trả lời:


732

Bạn muốn gọi .name trên lớp của đối tượng:

result.class.name

4
Khi tôi làm điều này, tôi nhận được các tên Mô-đun trước nó, vì vậy "Mô-đun :: SubModule :: Class", có cách nào để nhận được "Lớp"
Abe Petrillo

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

90
@Abe: thậm chí còn sạch hơn (ActiveSupport):result.class.name.demodulize
pseidemann

2
Đối với những người mới đến, bạn cũng có thể lấy tên lớp dưới dạng chuỗi bằng cách sử dụng lớp như thế này : User.name. User.to_sdường như cũng làm việc
Dan Polites

Phương thức demodulize xuất phát từ đây: apidock.com/rails/ActiveSupport/Inflector/demodulize (Bạn cần tải các chuỗi lạm dụng ActiveSupport để có thể sử dụng nếu, nếu bạn không phải là dự án Rails.)
Per Lundberg

118

Đây là câu trả lời đúng, được trích từ ý kiến ​​của Daniel Rikowski và pseidemann. Tôi mệt mỏi vì phải nhổ qua các bình luận để tìm câu trả lời đúng ...

Nếu bạn sử dụng Rails (ActiveSupport):

result.class.name.demodulize

Nếu bạn sử dụng POR (plain-ol-Ruby):

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

34

Cả hai result.class.to_sresult.class.namelàm việc.


34
Nhưng về mặt khái niệm, #name trả về tên, #to_s trả về một chuỗi đại diện, điều này xảy ra giống hệt với tên. Tôi muốn sử dụng #name, chỉ cần giữ lại hậu môn.
kch

7

Nếu bạn muốn lấy một tên lớp từ bên trong một phương thức lớp, class.namehoặc self.class.namesẽ không hoạt động. Đây sẽ chỉ là đầu ra Class, vì lớp của một lớp là Class. Thay vào đó, bạn chỉ có thể sử dụng name:

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

Foo::Bar.say_name

đầu ra:

I'm a Foo::Bar!

3

Trong trường hợp của tôi khi tôi sử dụng một cái gì đó như result.class.nametôi có một cái gì đó như Module1::class_name. Nhưng nếu chúng ta chỉ muốn class_name, hãy sử dụng

result.class.table_name.singularize

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.