2011-04-11 36 views

Trả lời

116

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

FooBar.name.underscore.to_sym 

Nhưng bạn sẽ phải cài đặt ActiveSupport để thực hiện đ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á underscore vào String 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ợ rằng đây là phần mở rộng của Rails. :) Đừng lo, vì tôi thực sự đang sử dụng Rails. –

+2

Sau đó, bạn nên gắn thẻ câu hỏi của mình 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. –

6

đầu tiên: gem install activesupport

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

Nên là 'FooBar.to_s.underscore.to_sym', vì tôi đang cố gắng chuyển đổi một lớp (là hằng số) thành biểu tượng, sau đó tôi có thể cấp cho [Factory Girl] (https: // github) .com/thinkbot/factory_girl). :) –

1

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

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 
+1

ActiveSupport có 'String # demodulize' sẽ xóa phần trước' :: '. – amoebe

+0

@amoebe - cảm ơn thông tin. Tùy thuộc vào những gì bạn làm việc trên mặc dù - bạn có thể không làm việc trên một ứng dụng đường ray (hoặc thậm chí một ứng dụng web). –

52

model_name trong Rails 4 trả về một đối tượng ActiveModel::Name trong đó có nhiều hữu ích hơn "ngữ nghĩa" thuộc tính 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 khớp với ý nghĩa mong muốn của bạn, có khả năng là như vậy. Ưu điểm:

  • dễ hiểu mã của bạn
  • ứng dụng của bạn sẽ vẫn làm việc ngay cả trong (không) sự kiện rằng Rails quyết định thay đổi một quy ước đặt tên.

BTW, human có lợi thế là nhận thức I18N.

+0

'model_name' cũng hoạt động cho các đối tượng mẫu. Ví dụ: 'foo_bar.model_name'. Nếu bạn muốn danh sách đầy đủ ghi 'foo_bar.model_name.inspect' trong bảng điều khiển đường ray hoặc trình gỡ rối của bạn – ivanxuu

Các vấn đề liên quan