Saya menggunakan baris berikut dalam initializer untuk memuat kode secara otomatis di /lib
direktori saya selama pengembangan:
config / initializers / custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(dari Rails 3 Quicktip: Auto reload folder lib dalam mode pengembangan )
Ini berfungsi dengan baik, tetapi terlalu tidak efisien untuk digunakan dalam produksi - Alih-alih memuat lib pada setiap permintaan, saya hanya ingin memuatnya saat start up. Blog yang sama memiliki artikel lain yang menjelaskan cara melakukan ini:
config / application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Namun, ketika saya beralih ke itu, bahkan dalam pengembangan, saya mendapatkan NoMethodErrors ketika mencoba menggunakan fungsi lib.
Contoh salah satu file lib saya:
lib / extensions.rb:
Time.class_eval do
def self.milli_stamp
Time.now.strftime('%Y%m%d%H%M%S%L').to_i
end
end
Memanggil Time.milli_stamp
akan melempar NoMethodError
Saya menyadari orang lain telah menjawab pertanyaan serupa pada SO tetapi mereka semua tampaknya berurusan dengan konvensi penamaan dan masalah lain yang saya tidak perlu khawatirkan sebelumnya - kelas lib saya sudah berfungsi untuk pemuatan per permintaan, saya hanya ingin mengubahnya untuk memuat per startup . Apa cara yang benar untuk melakukan ini?
Jawaban:
Saya pikir ini dapat menyelesaikan masalah Anda:
di config / application.rb :
dan simpan konvensi penamaan yang tepat di lib .
di lib / foo.rb :
di lib / foo / bar.rb :
jika Anda benar-benar ingin melakukan beberapa tambalan monyet di file seperti lib / extensions.rb , Anda mungkin memerlukannya secara manual:
di config / initializers / require.rb :
PS
Rails 3 Modul Isi Otomatis / Kelas oleh Bill Harding.
Dan untuk memahami apa sebenarnya yang dilakukan Rails tentang pemuatan otomatis?
baca Rails autoloading - cara kerjanya, dan saat itu tidak oleh Simon Coffey.
sumber
config.eager_load_paths << Rails.root.join('lib')
. Namun, itu memiliki kelemahan utama dalameager_load_paths
memuat semuanya dalam tugas juga. Saya pikir solusi lulalala lebih baik. Berikut adalah posting blog dengan rincian lebih lanjut: blog.arkency.com/2014/11/...Meskipun ini tidak langsung menjawab pertanyaan, tetapi saya pikir itu adalah alternatif yang baik untuk menghindari pertanyaan itu sama sekali.
Untuk menghindari semua
autoload_paths
ataueager_load_paths
kerumitan, membuat "lib" atau "misc" direktori di bawah direktori "app". Tempatkan kode seperti yang biasanya Anda lakukan di sana, dan Rails akan memuat file seperti bagaimana memuat (dan memuat kembali) file model.sumber
app
, saya harus melakukannya secara manual ...... atau perlu meletakkannya di jalur autload ..app/views
direktori yang tidak ditambahkan; atau lebih tepatnya dihapus secara eksplisit.lib
ini dimaksudkan untuk kode yang dapat diterapkan ke beberapa proyek dan mungkin dapat diekstraksi menjadi permata. Jika tidak membuat folder yang lebih tepat di bawah pencarian aplikasi sebagaiservices/
ataupresenters/
dan bahkan menundukkannya.Ini mungkin membantu seseorang seperti saya yang menemukan jawaban ini ketika mencari solusi untuk bagaimana Rails menangani pemuatan kelas ... Saya menemukan bahwa saya harus mendefinisikan
module
nama yang cocok dengan nama file saya dengan tepat, daripada hanya mendefinisikan kelas:Dalam file lib / development_mail_interceptor.rb (Ya, saya menggunakan kode dari Railscast :))
berfungsi, tetapi tidak dimuat jika saya tidak meletakkan kelas di dalam modul.
sumber
LOAD_PATH/module/class.rb
(garis bawah) di manaLOAD_PATH
berada di jalur pemuatan yang digunakan oleh aplikasi Ruby (autoload_paths dalam kasus Rails).lib
telah berfluktuasi dari yang dimuat secara otomatis oleh Rails ke tidak dimuat secara otomatis, dan dalam versi terbaru (> = Rails 3.x) itu tidak dimuat secara otomatis. Sihir apa pun yang membuat ini bekerja untuk Anda tidak disarankan. Mungkin itu adalah Railscast lama?Gunakan config.to_prepare untuk memuat tambalan / ekstensi monyet Anda untuk setiap permintaan dalam mode pengembangan.
akhir
sumber