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

99

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

FooBar.to_s.downcase.to_sym
Джош Гловер
источник

Ответы:

145

Rails поставляется с методом underscore, который позволяет преобразовывать строки CamelCased в строки с подчеркиванием_секрета. Итак, вы могли бы сделать это:

FooBar.name.underscore.to_sym

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

Если вы не хотите устанавливать 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
кикито
источник
1
Спасибо. Я боялся, что это расширение Rails. :) Не беспокойтесь, ведь я использую Rails.
Джош Гловер
2
Тогда вы должны были пометить свой вопрос соответствующим образом. Позволь мне сделать это за тебя ...
kikito
5
Нет, не ActiveRecord. ActiveSupport.
Рейн Хенрихс
Действительно, позвольте мне это изменить
kikito
2
как сделать обратное?
user1406062
73

Рельсы 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.

Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
model_nameтакже работает, например, с объектами. Пример: foo_bar.model_name. Если вам нужен полный список, напишите foo_bar.model_name.inspectв консоли rails или в вашем отладчике
ivanxuu
и я искал обратное / обратное classify, modelizeпохоже, не сработало.
Pysis,
7

сначала: gem install activesupport

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
ipsum
источник
Должно быть FooBar.to_s.underscore.to_sym, поскольку я пытаюсь преобразовать класс (который является константой) в символ, который я затем могу скормить Factory Girl . :)
Джош Гловер
2

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

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 есть функция, String#demodulizeкоторая удалит предыдущую часть ::.
амеб
@amoebe - спасибо за информацию. Однако это зависит от того, над чем вы работаете - возможно, вы не работаете с приложением rails (или даже с веб-приложением).
Луи Сэйерс