質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1943閲覧

rails RuboCop: Combine this loop with the previous loop. [Style/CombinableLoops]のエラーがでないようにしたい

k499778

総合スコア599

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/10/02 08:47

編集2021/10/02 11:39

前提・実現したいこと

現在Rails開発に携わっています。
CSVの一括登録・更新機能を実装しています。
以下のコードがRuboCop: Combine this loop with the previous loop. [Style/CombinableLoops]となっているため、のエラーがでないように修正したいです。

ruby

1value = row[:value] 2# 先に更新かどうかを確認し、そうでなければ登録する 3# 更新の場合 4(1..5).each do |i| 5 if fuga.id == hoge.public_send("fuga_#{i}_id") 6 updated_indexs << i 7 return { 8 "hoge_#{i}_id": fuga.id, 9 "hoge_value_#{i}": value, 10 } 11 end 12end 13# 登録の場合 14(1..5).each do |i| 15 unless updated_indexs.include?(i) 16 return { 17 "hoge_#{i}_id": fuga.id, 18 "hoge_value_#{i}": value, 19 } 20 end 21end 22 23 24

rubocopの修正方針は一つのループの中に入れろということだとは認識しています。

ただ、仕様的には、分ける必要があるのかなと思っており、rubocopエラーが出ないようにするにはどうしたらいいかアドバイスを頂きたいです。

以下仕様です。


①アップロードするCSVには複数行があり、それをアップロードしたらhogeテーブルの値(fuga_N_id,fuga_value_N)が更新されます。(一つのhoge.idに対して最大5行)
CSVの列にはid,fuga_id,fuga_valueがあります。

②hogeテーブルにはid,name,fuga_1_id ~ fuga_5_id, fuga_value_1 ~ fuga_value_5などがあり、
このCSVアップロードによってfuga_1_id ~ fuga_5_id, fuga_value_1 ~ fuga_value_5を登録・更新できます。
(hogeテーブルにおいてfuga_N_id,fuga_value_Nは横持ち。過去の経験からこの仕様に落ち着いた。)

③登録行か更新行はCSVに入力したfuga_idが、すでにhogeテーブルのfuga_1_id ~ fuga_5_idに存在していれば(一致していれば)更新、そうでなければ登録です。


①〜③のように、まず更新かどうかを確認してから、そうでなければ登録したいので、上記のコードのようにまず5回転してfuga_idがどれも一致しなければ、登録するようにしています。

それも踏まえてどのように修正すればいいかアドバイス頂けますと助かりますmm

試したこと

・RuboCop: Combine this loop with the previous loop. [Style/CombinableLoops]でググる
・他に参考がないか調べている

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/10/02 10:06 編集

> 仕様的には、分ける必要があるのかなと思っており どうしてそう考えていますでしょうか?
k499778

2021/10/02 10:26 編集

ご返答ありがとうございます! CSVのアップロードですでに更新された行を上書きしないようにしたいからです。 データが横持ちなので、更新行か判断するためには、一度 「hogeテーブルのfuga_1_id ~ fuga_5_id」 と「csvで入力されたfuga_id」が一致しているかどうかを確認する必要があると思っており、その後、登録するようにしています。更新の際に、どのカラム(fuga_N_id)を更新したかを保持しておき、それ以外のカラムを登録するようにしたいという意図でした。
maisumakun

2021/10/02 10:32

> 更新の際に、どのカラム(fuga_N_id)を更新したかを保持しておき、それ以外のカラムを登録するようにしたいという意図でした。 元のコードがreturnばかりで書かれていて、「1行でもマッチしたら即脱出」となっていますが、それは意図通りではないということでしょうか?
k499778

2021/10/02 11:11

意図通りです! CSVの一行に対して、もし更新であれば即脱出するように意図しています。 更新でなければ登録するという意図です。
k499778

2021/10/02 11:13 編集

CSVの次の2行目に対して、1行目で更新したカラムに対して登録しないようにしています。
maisumakun

2021/10/02 11:15

> 更新でなければ登録するという意図です。 えっと、returnすると、書かれているメソッド全体を抜けてしまうかと思うのですが、「更新でなければ登録する」という動作になるのでしょうか?
k499778

2021/10/02 11:32

例えば以下のようにDBの「fuga_2_id」に値がある場合 -------------------------------------------- CSVのデータ id | fuga_id | fuga_value 1 | 101 | 1000 hogeテーブル(DB) id | name | fuga_1_id | fuga_value_1 | fuga_2_id | fuga_value_2 | fuga_3_id | fuga_value_3 | fuga_4_id | fuga_value_4 | fuga_5_id | fuga_value_5 1 | 名前1| | | 101 | 0 | | | | | | -------------------------------------------- まずは更新行かどうか判断してから、そのカラムを(fuga_N_id)保持しておき、登録するようにその保持していたカラムを避けて登録するようにしています。 OKパターン(期待値) -------------------------------------------- hogeテーブル(DB) id | name | fuga_1_id | fuga_value_1 | fuga_2_id | fuga_value_2 | fuga_3_id | fuga_value_3 | fuga_4_id | fuga_value_4 | fuga_5_id | fuga_value_5 1 | 名前1| | | 101 | 1000 | | | | | | -------------------------------------------- もし更新行か確認せずに登録を行おうとすると結果以下となってしまう認識です。 NGパターン -------------------------------------------- hogeテーブル(DB) id | name | fuga_1_id | fuga_value_1 | fuga_2_id | fuga_value_2 | fuga_3_id | fuga_value_3 | fuga_4_id | fuga_value_4 | fuga_5_id | fuga_value_5 1 | 名前1| 101 | 1000 | 101 | 1000 | | | | | | --------------------------------------------
k499778

2021/10/02 11:34

>「更新でなければ登録する」という動作になるのでしょうか? CSVの入力データ「fuga_id」の値がhogeテーブルに設定されていなければ、更新処理内でreturnで抜けず、登録される認識です。
k499778

2021/10/02 11:36

例えば以下のパターン。hogeテーブルにfuga_idが設定されていない -------------------------------------------- CSVのデータ id | fuga_id | fuga_value 1 | 101 | 1000 hogeテーブル(DB) id | name | fuga_1_id | fuga_value_1 | fuga_2_id | fuga_value_2 | fuga_3_id | fuga_value_3 | fuga_4_id | fuga_value_4 | fuga_5_id | fuga_value_5 1 | 名前1|  |  |  |  |  |  |  |  |  | --------------------------------------------
k499778

2021/10/02 11:40

if fuga.id == hoge.public_send("fuga_#{i}_id") に合致しないときに登録処理になる認識です
guest

回答1

0

ベストアンサー

単にCopを無視させる、でいいのではないでしょうか?

公式にも、「書き換えれば意味が変わってくる恐れがある」と書いてあるようなCopです。

投稿2021/10/02 11:41

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/10/02 11:42

コメント形式で、「ここだけ」Style/CombinableLoopsを止める、というような書き方ができます。
k499778

2021/10/02 11:49 編集

>Safety The cop is unsafe, because the first loop might modify state that the second loop depends on; these two aren’t combinable. こちらですね!ありがとうございます。無視するという選択肢を今までしたことがあまりなかったので、参考になりましたmm
k499778

2021/10/02 13:50 編集

# rubocop:disable Style/CombinableLoops を処理に上部にコメントするよう対応しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問