2012-01-27 89 views
1

這是一個令人費解的例子如此忍受我:錯誤(命名)作用域

我有一個腳本,我開發過程中經常使用,這將消滅我的我的開發和測試數據庫的表,重新遷移,然後再種上它們。由於我在幾個地方使用了觸發器,我不得不使用rake db:migrate RAILS_ENV = test來正確地遷移我的測試數據庫。

一切都很好,直到我把我的測試環境中的config.cache_classes = true。然後,當耙子遷移運行在空數據庫上時,我會得到一個關於該表不存在的錯誤。與--trace運行這個,我發現它在我的對象之一炸燬時聲明瞭一個基本範圍:

scope :find_by_route_and_date, lambda { |route_id, date| 
    { 
     :conditions=>{:route_id=>route_id, :schedule_date=>date} 
    } 
    } 

範圍是在一個lambda,所以它不應該得到評估,但當我刪除cache_classes時,遷移工作正常。所以,對我來說,似乎它試圖緩存模型,窒息了範圍,因爲該表尚不存在,並且從不開始遷移。

我在想我嗎?其他人看過這個?如果我需要擦拭我的數據庫,是否需要關閉緩存,然後遷移,然後再打開它?

的Rails 3.2,紅寶石1.9.2,耙0.9.2.2

更新:

按照要求,這裏是堆棧跟蹤:https://gist.github.com/1705064

的order.rb:179是放置我的第一個範圍的地方,以及我上面列出的爆炸點。

+0

你得到了什麼棧跟蹤? – phoet 2012-01-27 23:15:10

+0

編輯包含鏈接到要點的痕跡 – 2012-01-30 15:49:47

+0

我覺得有點奇怪'order_controller.rb'在堆棧中。確定你沒有在你的耙子任務中做一些瘋狂的事情,那實際上是調用範圍? – phoet 2012-01-30 18:10:06

回答

2

這很有趣。我對堆棧跟蹤的閱讀是,rails試圖幫助你看看是否創建該範圍(即創建一個相同名稱的方法),你將通過覆蓋某些現有方法來創建問題。

這導致活動記錄下降respond_to它認爲您的範圍/方法名稱看起來很像動態查找程序。然後進一步:像動態查找器一樣,所有命名屬性都存在嗎?這是它試圖檢查不存在的表有什麼列,並且所有東西都炸了。

你可以(我認爲)做的幾件事情之一:

  • 範圍之前,定義一個類方法具有相同名稱的範圍,從而短路的respond_to調用(呸)
  • 更改範圍名
  • 覆蓋valid_scope_name

我仍然不知道爲什麼你不能設置從模式文件中的測試數據庫,如果有必要的架構自卸車設置爲:sql以便保留活動記錄本身不支持的內容。

+0

你死了。我將範圍重命名爲看起來不像尋找器,並且遷移運行良好。我會研究SQL翻車機,這對我的觸發器來說是一個更好的解決方案。謝謝! – 2012-01-30 19:27:26

0

通常,由於多種原因,您不應在遷移中引用模型。最值得注意的是,在第一次實例化模型時,大量關於表結構的信息被緩存。第二個最重要的問題是,如果將模型文件重構掉,那麼未來版本的應用程序可能不存在模型文件。

最好的做法是始終使用更多的低級別操作數據的方法,無論您的目錄的狀態如何,這些方法都能正常工作。一個優秀的遷移套件可以從原始狀態構建到最新版本,而不會掛上丟失的文件或方法。這就是爲什麼自給自足很重要。

您或許可以將此作用域重新編寫爲可以使用execute運行的更爲直接的事情。

如果因爲模式轉儲程序未正確記錄它們而使用觸發器並且在test環境中遇到問題,請改爲使用架構的:sql格式。這是一個更直接的副本,不應受Ruby-ized格式限制的影響。

+0

我的遷移不是指模型。這是在遷移完成之前發生的。 – 2012-01-30 19:20:11

+1

從我收集的模型沒有被用於遷移(雖然我同意這很危險) – 2012-01-30 19:23:48

+0

那很奇怪。看起來你有一個修復,但! – tadman 2012-01-30 20:57:50