Làm cách nào để chuyển đổi tên lớp Ruby thành biểu tượng được phân tách bằng dấu gạch dưới?


95

Làm cách nào để tôi có thể lập trình biến tên lớp FooBarthành một ký hiệu :foo_bar? ví dụ như một cái gì đó như thế này, nhưng xử lý trường hợp lạc đà đúng cách?

FooBar.to_s.downcase.to_sym

Câu trả lời:


141

Rails đi kèm với một phương thức được gọi là underscoresẽ cho phép bạn chuyển đổi các chuỗi CamelCased thành các chuỗi underscore_separated. Vì vậy, bạn có thể làm điều này:

FooBar.name.underscore.to_sym

Nhưng bạn sẽ phải cài đặt ActiveSupport để làm điều đó, như ipsum nói.

Nếu bạn không muốn cài đặt ActiveSupport chỉ cho điều đó, bạn có thể khỉ vá underscorevào Stringchính mình (chức năng gạch dưới được định nghĩa trong ActiveSupport :: Inflector ):

class String
  def underscore
    word = self.dup
    word.gsub!(/::/, '/')
    word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
    word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
    word.tr!("-", "_")
    word.downcase!
    word
  end
end

1
Cảm ơn. Tôi sợ đây là một phần mở rộng của Rails. :) Đừng lo lắng, vì tôi thực sự đang sử dụng Rails.
Josh Glover

2
Sau đó, bạn nên gắn thẻ câu hỏi của bạn cho phù hợp. Ở đây, hãy để tôi làm điều đó cho bạn ...
kikito

5
Không, không phải ActiveRecord. ActiveSupport.
Rein Henrichs

Thật vậy, hãy để tôi thay đổi nó
kikito

2
làm thế nào để làm điều ngược lại?
user1406062

72

Đường ray 4 .model_name

Trong Rails 4, nó trả về một ActiveModel::Nameđối tượng chứa nhiều thuộc tính "ngữ nghĩa" hữu ích hơn như:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

FooBar.model_name.human
#=> "Foo bar"

Vì vậy, bạn nên sử dụng một trong số đó nếu chúng phù hợp với ý nghĩa mong muốn của bạn, điều này có khả năng xảy ra. Ưu điểm:

  • dễ hiểu mã của bạn hơn
  • ứng dụng của bạn sẽ vẫn hoạt động ngay cả trong trường hợp (không chắc) mà Rails quyết định thay đổi quy ước đặt tên.

BTW, humancó lợi thế là nhận biết I18N.


model_namecũng hoạt động cho các đối tượng ví dụ. Ví dụ: foo_bar.model_name. Nếu bạn muốn danh sách ghi đầy đủ foo_bar.model_name.inspecttrong đường ray giao diện điều khiển hoặc debugger của bạn
ivanxuu

và tôi đang tìm kiếm điều ngược lại / đảo ngược, classify, modelizedường như không làm việc.
Lọc máu

7

đầu tiên: gem cài đặt activesupport

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym

Nên như vậy FooBar.to_s.underscore.to_sym, vì tôi đang cố chuyển đổi một lớp (là hằng số) thành một biểu tượng, sau đó tôi có thể cấp cho Factory Girl . :)
Josh Glover

2

Đây là những gì tôi đã làm:

module MyModule
  module ClassMethods
    def class_to_sym  
      name_without_namespace = name.split("::").last
      name_without_namespace.gsub(/([^\^])([A-Z])/,'\1_\2').downcase.to_sym
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

class ThisIsMyClass
  include MyModule
end 

ThisIsMyClass.class_to_sym #:this_is_my_class

3
ActiveSupport có String#demodulizemà sẽ loại bỏ phần trước đó ::.
amoebe

@amoebe - cảm ơn vì thông tin. Mặc dù vậy, phụ thuộc vào công việc của bạn - bạn có thể không làm việc trên ứng dụng rails (hoặc thậm chí là ứng dụng web).
Louis Sayers
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.