序章
複数のテーブルがあるアプリがあります。関連付けがある場合とない場合があります。
一部のテーブルには、約100,000のエントリを保持する必要があります。
このアプリは、Ruby1.9でRails3.2を使用しており、Herokuでホストされています。必要に応じて労働者にアクセスできます。
問題の要件
アプリの重要な要件は、ユーザーがデータをCSVとしてエクスポートできるようにすることです。この要件は、ユーザーがエクスポートするデータをフィルタリングできるようにすることですが、現時点では、次のように心配する必要はありません。以下のデータでは、エクスポートするデータをハードコーディングしていますが、これにより、テーブル全体をエクスポートするだけのrakeタスクを作成することはできなくなります。
また、実装されたメソッドは、不必要なコードの繰り返しを回避するために、複数のテーブルで使用できるように因数分解する必要があります。
現在のソリューション
アプリにdelayed_jobを実装し、ジョブでCSV生成を実行しています。これを行っている間、私はここhttp://www.ayokasystems.com/blog/delegating-long-running-jobs-in-rails/from'abdullah 'にある解決策に従っています。
アイデアは、CSV形式でデータを生成し、それをUserJobsテーブルのLONGTEXTフィールドに保存して、ユーザーが完了後、後でダウンロードできるようにすることです。
問題
上記のチュートリアルで使用した方法は、一度に100,000レコードのジョブを実行するまで、アプリで正常に機能します。これを克服するために、performメソッドにcool find_each関数を追加しようとしましたが、遅延したジョブワーカーは、処理しようとするたびにエラーを報告します。
[Worker(host:*** pid:18637)] ReportJob failed with NoMethodError: undefined method `each' for #<Title:0x007ff20c1ec1b0> - 0 failed attempts
[Worker(host:*** pid:18637)] ReportJob failed with NoMethodError: undefined method `each' for #<Title:0x007ff20ec47f18> - 1 failed attempts
[Worker(host:*** pid:18637)] 2 jobs processed at 10.5219 j/s, 2 failed ...
私のperformメソッドのコードは次のとおりです。
def perform
Title.find_each do |titles|
csv_data = CSV.generate do |csv|
titles.each do |t|
csv << t.to_csv
end
end
user_job = UserJob.find(user_job_id)
user_job.update_attribute :data, csv_data
end
end
誰かが問題が何であるかを見ることができますか、私は私が物事をループしている方法で私がちょうど愚かな間違いをしたと思っています。
問題の要件を達成する方法について他の提案を歓迎しますが、Herokuには制限があることを覚えておいてください。