Pertanyaan Bagaimana cara mengonversi nama kelas Ruby menjadi simbol yang dipisahkan garis bawah?


Bagaimana saya bisa mengubah nama kelas secara terprogram, FooBar, menjadi simbol, :foo_bar? misalnya sesuatu seperti ini, tapi itu menangani kasus unta dengan benar?

FooBar.to_s.downcase.to_sym

75
2018-04-11 14:03


asal


Jawaban:


Rel dilengkapi dengan metode yang disebut underscore yang akan memungkinkan Anda mengubah string CamelCased menjadi string underscore_separated. Jadi Anda mungkin bisa melakukan ini:

FooBar.name.underscore.to_sym

Tetapi Anda harus menginstal ActiveSupport hanya untuk melakukan itu, seperti yang dikatakan ipsum.

Jika Anda tidak ingin menginstal ActiveSupport hanya untuk itu, Anda dapat melakukan monkey-patch underscore ke String diri Anda sendiri (fungsi garis bawah didefinisikan dalam 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

119
2018-04-11 14:15



nama model di Rails 4 mengembalikan sebuah ActiveModel::Name objek yang berisi banyak atribut "semantik" yang lebih bermanfaat seperti:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Jadi Anda harus menggunakan salah satu dari itu jika mereka cocok dengan makna yang Anda inginkan, yang mungkin adalah masalahnya. Keuntungan:

  • lebih mudah untuk memahami kode Anda
  • aplikasi Anda akan tetap berfungsi bahkan dalam kejadian (tidak mungkin) bahwa Rails memutuskan untuk mengubah konvensi penamaan.

BTW, human memiliki keuntungan menjadi I18N sadar.


55
2017-09-03 09:09



pertama: gem install activesupport

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

6
2018-04-11 14:09



Inilah yang saya maksud:

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

2
2017-09-20 10:56