Как мне преобразовать имя класса Ruby в символ, разделенный подчеркиванием? - PullRequest
87 голосов
/ 11 апреля 2011

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

FooBar.to_s.downcase.to_sym

Ответы [ 4 ]

134 голосов
/ 11 апреля 2011

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

FooBar.name.underscore.to_sym

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

Если вы не хотите устанавливать ActiveSupport только для этого, вы можете самостоятельно обезопасить underscore от *1007* (функция подчеркивания определена в 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
65 голосов

Рельсы 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 обладает тем преимуществом, что знает I18N.

6 голосов
/ 11 апреля 2011

первый: gem install activesupport

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
2 голосов
/ 20 сентября 2013

Вот что я сделал:

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
...