2015-10-15 50 views
1

的JRuby,Rails的3斷裂協會/關聯對象集合到紅寶石較小協會/關係集合on Rails的

我有一段代碼,用於查詢的數表,通過關聯相關的,返回一個組合的結果設置爲一個ActiveRecord ::關係。我的問題是,當這個函數檢索一個非常大的結果集,並試圖用它做一些事情(在我的情況下,創建一個.xls文件),JVM錯誤,報告GC內存堆問題。

問題部分歸咎於所有這些記錄在嘗試處理.xls導出時都保存在內存中,以及JRuby的可疑垃圾回收器 - 但是,所有這些記錄都不應該立即處理!所以我的解決方案是將這些記錄分成更小的塊,將它們寫入文件並重復。

但是,在我所有其他約束中,我需要使用的下一部分代碼需要傳遞給它的關係對象。以前,這是整個結果集,但在這一點上,我已經把它分成了更小的位(爲了參數,可以說100個記錄)。

在這一點上,你可能會想,是啊 - 有什麼問題?好了,下面看我的例子代碼:

#result_set = relation object 
result_set.scoped.each_slice(100) do |chunk| 
    generic_filter = App::Filter.new(chunk, [:EXCEL_EXPORT_COLUMNS]) #<-- errors here 

    #do some stuff 
    generic_filter.relation.each_with_index do |work_type, index| 
    xls_doc.row(index + 1).concat(generic_filter.values_for_row(work_type)) 
    DATE_COLUMN_INDEX.each do |column_index| 
     xls_doc.row(index + 1).set_format column_index, 
      ::Spreadsheet::Format.new(number_format: 'DD-MM-YYYY') 
    end 
    end 
    [...] #some other stuff 
end  

正如你所看到的,我分裂result_set到100條記錄小塊,並把它傳遞給應用程序過濾::類,預計關係對象。但是,使用each_slicein_groups將result_set分割爲更小的塊會導致塊中出現錯誤,因爲這兩個方法返回的是結果數組,而不是關係。

我是相當新的Ruby on Rails的,所以我的問題是:

  • 事實上是一個關係的對象/收集/或類似預 定義的查詢,就像一個準備好的聲明?
  • 是否可以使用類似於 each_slice或in_groups的方法返回更小的關係對象,並按預期處理它們?

任何指標/建議將受到歡迎,謝謝!

回答

1

關係是構建SQL查詢(INSERT,SELECT,DELETE等)的一種幫助器。在你的例子中,你用each_slice觸發SELECT查詢,並得到結果數組。

我沒有檢查,我不確定each_slice正在做你想做的事...你應該檢查find_each來代替。

你或許應該做這樣的事情:

# do what you need with the relation but do NOT trigger the query 
generic_filter = App::Filter.new(result_set.scoped, [:EXCEL_EXPORT_COLUMNS]) #<-- errors here 

# trigger the query by slice 
generic_filter.relation.find_each do |chunk| 
    chunk.each_with_index do |work_type, index| 
    xls_doc.row(index + 1).concat(generic_filter.values_for_row(work_type)) 
    DATE_COLUMN_INDEX.each do |column_index| 
     xls_doc.row(index + 1).set_format column_index, 
      ::Spreadsheet::Format.new(number_format: 'DD-MM-YYYY') 
    end 
    end 
end