Jak przekonwertować nazwę klasy Ruby na symbol rozdzielany podkreśleniem?


98

Jak programowo zmienić nazwę klasy FooBarna symbol :foo_bar? np. coś w tym rodzaju, ale czy to dobrze radzi sobie z wielbłądem?

FooBar.to_s.downcase.to_sym

Odpowiedzi:


145

Railsy są wyposażone w metodę o nazwie underscore, która pozwoli ci przekształcić ciągi CamelCased w ciągi podkreślone_separated. Więc możesz to zrobić:

FooBar.name.underscore.to_sym

Ale będziesz musiał zainstalować ActiveSupport, aby to zrobić, jak mówi ipsum.

Jeśli nie chcesz instalować ActiveSupport tylko po to, możesz małpa-patch underscoredo Stringsiebie (funkcja podkreślenia jest zdefiniowana w 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
Dzięki. Bałem się, że to rozszerzenie Railsów. :) Nie martw się, tak naprawdę używam Railsów.
Josh Glover,

2
W takim razie powinieneś był odpowiednio oznaczyć swoje pytanie. Pozwól, że zrobię to za Ciebie ...
kikito

5
Nie, nie ActiveRecord. ActiveSupport.
Rein Henrichs

Rzeczywiście, pozwólcie, że to
zmienię

2
jak zrobić odwrotnie?
user1406062

73

Szyny 4 .model_name

W Railsach 4 zwraca ActiveModel::Nameobiekt, który zawiera wiele przydatnych, bardziej „semantycznych” atrybutów, takich jak:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Powinieneś więc użyć jednego z nich, jeśli pasują do twojego pożądanego znaczenia, co prawdopodobnie ma miejsce. Zalety:

  • łatwiejsze do zrozumienia kodu
  • Twoja aplikacja będzie nadal działać nawet w (mało prawdopodobnym) przypadku, gdy Railsy zdecydują się zmienić konwencję nazewnictwa.

BTW, humanma tę zaletę, że jest świadomy I18N.


model_namedziała również na przykład obiekty. Np foo_bar.model_name. : . Jeśli chcesz mieć pełną listę napisz foo_bar.model_name.inspectw konsoli
railsów

i szukałem przeciwieństwa / odwrotności, wydawało się classify, modelizeże nie działa.
Pysis

7

po pierwsze: gem install activesupport

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

Powinno być FooBar.to_s.underscore.to_sym, ponieważ próbuję przekształcić klasę (która jest stałą) w symbol, który mogę następnie przekazać Factory Girl . :)
Josh Glover

2

Oto, do czego poszedłem:

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 ma, String#demodulizektóry usunie część wcześniej ::.
ameba

@amoebe - dzięki za informację. Zależy to jednak od tego, nad czym pracujesz - możesz nie pracować z aplikacją railsową (lub nawet aplikacją internetową).
Louis Sayers,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.