[英]How does Rails find models and controllers? How can I get it to load more models?
我正在嘗試在app/models/gamestate.rb
創建一個非ActiveRecord模型。 然后在我的控制器(PlayController)內我應該可以做GameState.new
,對嗎? 不去:
NameError (uninitialized constant PlayController::GameState):
app/controllers/play_controller.rb:23:in `play'
(至少在開發環境中)
但! 如果我有一個名為app/models/play.rb
,那么它會自動加載,我可以做Play.new
。
所以我的問題是:Rails如何知道要加載哪些類? 從play#action
到PlayController
到app/controllers/play_controller.rb
到app/models/play.rb
,它會做什么樣的名稱app/models/play.rb
?
它似乎非常脆弱,但也許更好地了解它的工作原理會有所幫助。
最后,我怎樣才能加載app/models/gamestate.rb
?
Heikki是對的,但沒有解釋為什么會這樣。 Rails將app
內的每個文件夾添加到autoload_path配置設置中。 當一個未知的常量被要求時,Rails會在這條路徑中查找常量並且如果它找不到文件名 - 例如gamestate.rb
與正確的game_state.rb
- 那么它贏了無法加載此文件中定義的常量。
如果模型文件名是gamestate.rb,那么類名應該是Gamestate而不是GameState(或者game_state.rb - > GameState)。 多數民眾贊成Rails命名約定。 我建議盡可能遵循它們。 事情就這樣流暢得多。
關於Ruby / Rails命名約定的文章: http : //itsignals.cascadia.com.au/?p = 7
為了擴展Ryan的答案,這是一個Rails慣例。 在Rails 3中,activesupport / lib / dependencies.rb有一個名為load_missing_constant的方法,當你引用GameState並且尚未加載時,它會查找GameState。 它需要丟失常量'GameState',在其上調用'下划線'將其轉換為game_state,然后在autoload_paths中搜索它。 如果它找到具有該名稱的文件(以.rb結尾),則會加載它。
在生產模式中,game_state.rb將被預先加載(假設它在一個autoload_paths中),因此GameState類常量將在您引用它時加載。 在這種情況下不需要修剪。
您可能希望將非AR模型放在單獨的文件夾中; 例如,您可以添加到config / application.rb中的自動加載路徑,例如:
config.autoload_paths += %W(#{config.root}/lib)
然后你可以把類GameState放在lib / game_state.rb中,Rails會找到它。
順便說一句,我不是Rails專家,但是解決這個問題的一種方法是運行Ruby調試器並設置斷點,其中“魔術”似乎發生; 然后你可以使用where或caller(0)來回溯並找到相關的Rails代碼。 有時需要花幾次嘗試使用策略斷點(或者通過在源代碼中添加調試器),但是一旦看到它逐行發生,通常就會有意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.