teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2018/10/11 10:16

投稿

takahashim
takahashim

スコア1877

answer CHANGED
@@ -3,4 +3,45 @@
3
3
 
4
4
  また、`find_each`などの代わりに `pluck` を使って、ARオブジェクトを作らないようにすることも検討した方がよいかと思います。
5
5
 
6
- * [Rails: pluckでメモリを大幅に節約する(翻訳)](https://techracho.bpsinc.jp/hachi8833/2018_09_26/62333)
6
+ * [Rails: pluckでメモリを大幅に節約する(翻訳)](https://techracho.bpsinc.jp/hachi8833/2018_09_26/62333)
7
+
8
+ -----
9
+ (追記)
10
+
11
+ あああー、これはぜんぜん違う話でしたね。
12
+
13
+ ```ruby
14
+ items = Item.all
15
+ ```
16
+
17
+ がダメです。allはNGです。
18
+ RailsガイドのActive Record クエリインターフェイスの[1.2 複数のオブジェクトをバッチで取り出す](https://railsguides.jp/active_record_querying.html#%E8%A4%87%E6%95%B0%E3%81%AE%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E3%83%90%E3%83%83%E3%83%81%E3%81%A7%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99)に書かれている、「# このコードはテーブルが大きい場合、メモリを大量に消費する可能性あり」の例そのものになってます。
19
+
20
+ recordsを渡すのではなく、
21
+
22
+ ```
23
+ def index
24
+ render_csv
25
+ end
26
+ ```
27
+
28
+ みたいにしておいて、
29
+
30
+ ```ruby
31
+ def render_csv
32
+ ## (略)
33
+ self.response_body = Enumerator.new do |y|
34
+ names = Item.csv_column_names
35
+ y << encode_sjis(names.values.to_csv)
36
+
37
+ Item.find_in_batches do |group|
38
+ group.each do |record|
39
+ values = record.csv_column_values
40
+ y << encode_sjis(values.map{|k, v| v.call(record)}.to_csv)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ ```
46
+
47
+ というように、`find_in_batches`で初めてオブジェクトを生成するようにしないと、`find_in_batches`とかを使うメリットがないです。