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

97

Bagaimana cara saya secara terprogram mengubah nama kelas FooBar,, menjadi simbol :foo_bar,? Misalnya sesuatu seperti ini, tapi itu menangani kotak unta dengan benar?

FooBar.to_s.downcase.to_sym
Josh Glover
sumber

Jawaban:

143

Rails dilengkapi dengan metode underscoreyang memungkinkan Anda untuk 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 underscoreke Stringdiri Anda sendiri (fungsi garis bawah ditentukan di 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
kikito
sumber
1
Terima kasih. Saya takut ini adalah ekstensi Rails. :) Jangan khawatir, karena saya sebenarnya menggunakan Rails.
Josh Glover
2
Maka Anda seharusnya telah menandai pertanyaan Anda dengan tepat. Di sini, biarkan saya melakukannya untuk Anda ...
kikito
5
Tidak, bukan ActiveRecord. ActiveSupport.
Rein Henrichs
Memang, izinkan saya mengubahnya
kikito
2
bagaimana melakukan kebalikannya?
pengguna1406062
73

Rel 4 .model_name

Di Rails 4, ia mengembalikan ActiveModel::Nameobjek yang berisi lebih banyak atribut "semantik" yang berguna 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 mereka jika cocok dengan makna yang Anda inginkan, yang kemungkinan besar terjadi. Keuntungan:

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

BTW, humanmemiliki keuntungan karena sadar I18N.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
model_namejuga berfungsi untuk objek contoh. Ex: foo_bar.model_name. Jika Anda ingin daftar lengkap tulis foo_bar.model_name.inspectdi konsol rel atau debugger Anda
ivanxuu
dan saya sedang mencari sebaliknya / terbalik, classify, modelizetampaknya tidak bekerja.
Pysis
7

pertama: gem instal aktif dukungan

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
ipsum
sumber
Seharusnya FooBar.to_s.underscore.to_sym, karena saya mencoba mengonversi kelas (yang merupakan konstanta) menjadi simbol, yang kemudian dapat saya berikan ke Factory Girl . :)
Josh Glover
2

Inilah yang saya lakukan:

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
Louis Sayers
sumber
3
Memiliki ActiveSupport String#demodulizeyang akan menghapus part sebelumnya ::.
amoebe
@ amoebe - terima kasih atas infonya. Tergantung pada apa yang Anda kerjakan - Anda mungkin tidak mengerjakan aplikasi rel (atau bahkan aplikasi web).
Louis Sayers