2011-10-10 34 views
1

我report.rb類包含以下代碼:實例變量似乎失去其價值

def create 
    @start_term = ::SchoolTerm.find(1705265) 
    @end_term = ::SchoolTerm.currently_enrolling 

    current = 0 
    total = all_terms.size 

    @terms = {} 

    all_terms.each do |t| 
     @terms[t.id] = Business::Sales::RevenueByWeek::Term.new(t) 
     Rails.logger.info("#{@terms} is @terms in report#create") 
     current += 1 
     self.progress = 100.0 * (Float(current)/Float(total)) 
    end 
    end 

    def all_terms 
    ::SchoolTerm.between(@start_term, @end_term) - RevenueGoal.terms_without 
    end 

    def each 
    Rails.logger.info("#{@terms} is @terms in report.each") 
    all_terms.each do |t| 
     yield @terms[t.id] if @terms[t.id] 
    end 
    end 

記錄儀線內創建顯示,@terms同時通過不同的學期循環具有正確的價值觀。但是,每種方法中的記錄器行都顯示@terms爲空。當我嘗試加載的報告,我得到這個錯誤:

You have a nil object when you didn't expect it! 
You might have expected an instance of ActiveRecord::Base. 
The error occurred while evaluating nil.[] 

Extracted source (around line #24): 

    </tr> 
    </thead> 

    <% report.each do |term| %> 
    <tbody class="term_<%= term.id %>"> 
     <tr class="term"> 
     <th><%= term.term %></th> 

我已經驗證業務::銷售:: RevenueByWeek :: Term.new返回正確的數據。任何想法,爲什麼我得到這個零對象錯誤?我認爲實例變量保留了它們的值,但不知何故,這個變量會丟失。

謝謝。

+0

請顯示您如何使用此代碼,流程如何。 –

回答

1

我假設report.rb是一個活躍的記錄模型。在該框架中,#create並不意味着是構造函數,它僅在基礎表中創建行。不過,我看到你在那裏設置了@terms = {}

如果您的報表實例從數據庫中查詢出來,#create永遠不會運行,所以您的成員永遠不會被初始化。

我建議你隱藏了一個名爲terms方法背後的@terms(甚至是內部的)使用(也就是說,除非你已經宣佈它作爲AR屬性,或類似)。您的方法懶惰初始化成員作爲需要。

0

report.rb是不是活動記錄模型 - 不使用數據庫表。 創建方法用於創建報表實例,並將調用級聯到獲取報表值所需的其他類,如Term.new調用。

創建方法結束後,呈現一個視圖 - 上面的錯誤來自該視圖中的一個部分。

我已經把各種記錄通話中創建方法來驗證它確實得到調用,並且在創建方法變量@terms是什麼,我希望它是。我無法弄清楚爲什麼填充的@terms散列在每個方法中都不可用。該創建方法記錄器調用每個方法記錄的調用之前出現,而@terms是好的在創建每個空或零。 @terms是否應該保留整個實例的價值 - 並且不要將其他方法隱藏起來?

0

我解決了這個問題。發生的事情是@terms變量應該被寫入緩存。我們正在使用memcached,並且@terms數據的大小超過1 MB,所以Cache.write語句失敗。然後,當@terms需要從'each'方法的緩存中提取時,那裏什麼也沒有。這個快速而骯髒的解決方案是減少@term數據的大小,以便Cache.write成功。長期的解決方案是用Resque替換memcached,Resque對與一個鍵相對應的數據大小沒有這樣的限制。