Как преобразовать имя класса Ruby в символ с разделителем подчеркивания?

Как я могу программным образом превратить имя класса FooBar в символ :foo_bar? например что-то вроде этого, но верно ли это для верблюда?

FooBar.to_s.downcase.to_sym

Ответ 1

Rails поставляется с методом под названием underscore, который позволит вам преобразовывать строки CamelCased в underscore_separated строки. Таким образом, вы можете сделать это:

FooBar.name.underscore.to_sym

Но вам нужно будет установить ActiveSupport только для этого, как говорит ipsum.

Если вы не хотите устанавливать ActiveSupport только для этого, вы можете обезьян-патч underscore в String самостоятельно (функция подчеркивания определена в ActiveSupport:: инфлектор):

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

Ответ 2

Rails 4 .model_name

В Rails 4 он возвращает объект ActiveModel::Name который содержит много полезных более "семантических" атрибутов, таких как:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Таким образом, вы должны использовать один из них, если они соответствуют вашему желаемому значению, что, вероятно, имеет место. Преимущества:

  • легче понять ваш код
  • Ваше приложение будет по-прежнему работать даже в (маловероятном) случае, когда Rails решит изменить соглашение об именах.

Кстати, у human есть преимущество в том, что я осведомлен.

Ответ 3

сначала: gem install activesupport

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

Ответ 4

Вот что я пошел:

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