Як перетворити назву класу Ruby на символ, підкреслений підкресленням?


95

Як я можу програмно перетворити назву класу FooBar, на символ :foo_bar,? наприклад щось подібне, але це правильно справляється з випадком верблюда?

FooBar.to_s.downcase.to_sym

Відповіді:


141

Rails поставляється з методом, який називається, underscoreщо дозволить вам перетворити рядки CamelCased в рядки, виділені підкресленням. Отже, ви можете зробити це:

FooBar.name.underscore.to_sym

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

Якщо ви не хочете встановлювати ActiveSupport тільки для цього, ви можете перенести мавпу underscoreв Stringсебе (функція підкреслення визначена в 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
Дякую. Я побоювався, що це розширення Rails. :) Не хвилюйтесь, оскільки я фактично використовую Rails.
Джош Гловер

2
Тоді ви мали би відповідно позначити своє питання. Ось, дозвольте мені зробити це за вас ...
kikito

5
Ні, не ActiveRecord. ActiveSupport.
Рейн Генріхс

Дійсно, дозвольте мені це змінити
kikito

2
як зробити реверс?
user1406062

72

Рейки 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на консоль
рейлів

і я дивився на протилежну / назад, classify, modelizeне схоже на роботу.
Pysis

7

перше: підтримка активної роботи з gem

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

Має бути 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

@amoebe - дякую за інформацію. Залежить від того, над чим ви працюєте - можливо, ви не працюєте над додатком рейки (або навіть веб-додатком).
Louis Sayers,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.