2011-03-03 60 views
2

類似的問題已被詢問了很多次。然而,我有一個略有不同的情況,我仍然在開發Rails 3應用程序時找到一個乾淨的解決方案來解決以下問題:我有一個ruby代碼位於單個文件中。此代碼是一個模塊MyModule,其中包含一堆類。我無法修改此代碼,因爲它是由外部工具自動生成的。文件名是my_module.rb,它位於lib文件夾中。這是不屬於主Web應用程序的代碼的常用位置。一旦我通過修改application.rb中的config.autoload_paths設置訪問我的某個應用控制器中的MyModule,我確定它是自動加載的。重新打開位於lib文件夾中的類(Rails 3)

現在我需要重新打開MyModule中的其中一個類。我創建了一個單獨的文件some_class.rb這裏我把下面的代碼:

 
    class MyModule::SomeClass 
     def some_new_method 
      ... 
     end 
    end 

我的問題是:是什麼把這個代碼的最佳地點?什麼應該是文件的名稱?

的事情我想:

  1. 代碼放置到initializers文件夾中。它在生產環境中工作正常。但是,由於initiliazers文件夾中的代碼在服務器啓動時加載一次,並且在每個請求上重新加載lib,因此它會在development中中斷。因此,開發中的第一個請求正常工作,但是,後續請求失敗。此外,我不喜歡將代碼放入initializers,因爲它不是真正的初始化片,而是業務邏輯的一部分。
  2. 將代碼放入lib文件夾中也不起作用。它沒有加載。只有my_module.rb是。
  3. 將代碼放入libapp下的其他文件夾,然後在控制器中將其明確地加入。它再次在生產中工作,但由於上述情況#1中的相同原因而未能開發。
  4. 我關閉了自動加載功能,將my_module.rbsome_class.rb都放入lib文件夾中,並將require放入初始化程序中。我認爲這是最好的方法。缺點是我仍然需要創建一個自定義初始化程序,並且代碼不會被延遲加載。

UPDATE: 5.由於RAGGI的建議,用自動加載打開,我在我的控制器把require_dependency 'some_class'。在這種情況下,some_class.rb以開發模式加載到每個請求上。這是我首選的方法。但是,它仍然需要某種require :)

請記住lib文件夾中的文件是自動加載的。只有在使用rails無法找到的模塊或類時,Rails纔會檢查文件夾。文件名必須遵循命名慣例,因此名稱爲my_module.rb

我不知道是否有解決方案時,這兩個文件是自動加載懶惰沒有任何require陳述。

回答

1

你嘗試require_dependency在你的控制器,而不是需要?

+0

剛試過。是的,它的工作原理。我想沒有任何解決方案可以在不需要'require'或'require_dependency'語句的情況下自動加載這兩個文件。我相信,我的問題的答案是否定的。我提出了你的回答,但對於這個建議。 – GregK 2011-03-07 18:45:14

0

您可以將這些文件放在lib目錄中,並讓它們不會被延遲加載,而是自動加載到config/application中。RB,如果你想將文件放入不同的子文件夾:

config.autoload_paths += Dir["#{config.root}/lib/**/"] 

或者如果你只需要lib文件夾:

config.autoload_paths += %W(#{config.root}/lib) 
+0

這就是我所做的。我編輯了我的問題,提到這一點。但是,問題是my_module.rb是自動加載的,但some_class.rb不是。 – GregK 2011-03-03 23:20:45

0

TL; DR:隱藏require以外的主線代碼。

在開發過程中嘗試在模塊中創建驗證器時遇到了類似的問題。當我試圖解決聽起來像是同樣的問題時,我碰到了this blog entry

// Added to application.rb 
Rails::Application.config.autoload_paths.each do |d| 
    Dir["#{d}/*.rb"].each do |p| 
    puts "Requiring '#{p}' on startup..." 
    require p 
    end 
end