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

回答編集履歴

2

---

2015/03/18 23:05

投稿

hello-world
hello-world

スコア1342

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  `update_all`は更新したデータの行数を返すため、`checked_item`がFixnumになっています。
2
2
 
3
- ----
3
+ ---
4
4
 
5
5
  追記:
6
6
 

1

大幅な追記

2015/03/18 23:05

投稿

hello-world
hello-world

スコア1342

answer CHANGED
@@ -1,1 +1,45 @@
1
- `update_all`は更新したデータの行数を返すため、`checked_item`がFixnumになっています。
1
+ `update_all`は更新したデータの行数を返すため、`checked_item`がFixnumになっています。
2
+
3
+ ----
4
+
5
+ 追記:
6
+
7
+ 些事ですが
8
+ - データ数がゼロなら、`each`で回しても問題ありません。
9
+ - データが多くなることを考えると、`each`より`find_each`を使う方がよいです。
10
+ - 複数のデータを変更するばあいは、`transaction`で囲った方がよいでしょう。
11
+
12
+ ですので
13
+ ```lang-ruby
14
+ # before
15
+ unless no_check_item.count == 0
16
+ no_check_item.each do |item|
17
+ Navi.create(exhibitor: item.user_id, item_id: item.id, status: 1)
18
+ item.update({limit_check: true})
19
+ end
20
+ end
21
+ ```
22
+ は、
23
+ ```lang-ruby
24
+ #after
25
+ Item.transaction do
26
+ no_check_item.find_each do |item|
27
+ Navi.create(exhibitor: item.user_id, item_id: item.id, status: 1)
28
+ item.update(limit_check: true)
29
+ end
30
+ end
31
+ ```
32
+ とするのがよいでしょう。
33
+
34
+ また、これ以降`no_checked_item`のインスタンスには触れない(※)のであれば最初のように`update_all`を使ってもよいと思います。
35
+ ※)`update_all`はデータベースを直接変更するので、Railsから見える`no_check_item`の中身はチェックされていない状態が続きます。チェックされた状態のインスタンスが必要であればリロードする必要があります。
36
+ ```lang-ruby
37
+ Item.transaction do
38
+ no_check_item.find_each do |item|
39
+ Navi.create(exhibitor: item.user_id, item_id: item.id, status: 1)
40
+ end
41
+ no_check_item.update_all(limit_check: true) # 戻り値は読まなくてOK
42
+ end
43
+ ```
44
+
45
+ ループ中の`create`のパフォーマンスも気になるようであれば、`activerecord-import`というgemを利用するのがよいでしょう。