Railsポートフォリオのリファクタリング（Exceへの書き出し）

## はじめに
実務未経験からエンジニア転職を目指して、現在転職活動中です。  
企業の方からサイト経由で「可読性が悪い」とフィードバックいただいたので、ここは読みづらいだろうなと思ったところを修正しています。

## やろうとしている処理
rubyXLというRubyのライブラリを使ってPDFから取得したテキストデータをエクセルに書き出します。

### 元のコード
```ruby
pdf_data.each_with_index do |subject_data, sub_i|
  worksheet.add_cell(sub_i + 1, 0, subject_number)
  worksheet.add_cell(sub_i + 1, 1, "CHIBA#{sub_i + 1}")
  worksheet.add_cell(sub_i + 1, 2, pdf_data[sub_i][0])
  worksheet.add_cell(sub_i + 1, 3, pdf_data[sub_i][1])
  worksheet.add_cell(sub_i + 1, 4, pdf_data[sub_i][2])
  worksheet.add_cell(sub_i + 1, 5, pdf_data[sub_i][3])
  worksheet.add_cell(sub_i + 1, 6, pdf_data[sub_i][4])
  worksheet.add_cell(sub_i + 1, 7, pdf_data[sub_i][5])
  worksheet.add_cell(sub_i + 1, 8, pdf_data[sub_i][6])
  worksheet.add_cell(sub_i + 1, 9, pdf_data[sub_i][7])
  worksheet.add_cell(sub_i + 1, 10, pdf_data[sub_i][8])
  worksheet.add_cell(sub_i + 1, 11, pdf_data[sub_i][9])
  worksheet.add_cell(sub_i + 1, 12, pdf_data[sub_i][10])
end
```

`pdf_data`には、以下のように1人ずつのデータが配列で格納されています。

```
[["4", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "1", "3", "3", "23"],
 ["5", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "2", "5", "3", "27"]]
```

2次元配列から1人分ずつ取り出して、Excelの1行ごとに1列目から13列目に書き出します。


![スクリーンショット 2024-10-20 午後3.27.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/005f911e-9dce-4092-844a-ec047c088885.jpeg)

Excelに書き出したいデータは以下のとおりです。
- 1列目：index + 1
- 2列目：指定の文字列 + index
- 3列目以降：pdf_data配列から該当する人のデータを順番に書き出す

### add_cellメソッドの使い方
```ruby 
require 'rubyXL'

workbook = RubyXL::Workbook.new
worksheet.add_cell(0, 0, 'A1')  # Sets cell A1 to string "A1"
```
第1引数と第2引数で入力するセルを指定して、第3引数で値を指定します。

- 第1引数：n行目
- 第2引数：n列目
- 第3引数：入力する値

出典：https://github.com/weshatheleopard/rubyXL

### 失敗
```ruby
pdf_data.each_with_index do |subject_data, subject_i|
  subject_num = subject_i + 1
  subject_data.each_with_index do |score, score_i|
  if score_i == 0
    worksheet.add_cell(subject_num, score_i, subject_num)
  elsif score_i == 1
    worksheet.add_cell(subject_num, score_i, "CHIBA#{subject_num}")
  else
    worksheet.add_cell(subject_num, score_i, score)
  end
end
```

最後の2列が空欄になってしまいました。
![スクリーンショット 2024-10-20 午後4.09.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/15a55912-3c25-7cf7-95ae-7aa220cc2400.png)

`pdf_data`配列の中の1人分のデータの要素数が11で、  
その中でループを回して1回目と2回目は値を取り出さず、
3回目以降に値を取り出しているため、 
最後の2つ分が取得できていません。

### 試したこと①
Excelに書き出す処理を行う前に、pdf_data配列を以下のように変更しました。

before：`[[1人目の得点データ], [2人目の得点データ]・・・`
after：`[1, 指定の文字列+1, [1人目の得点データ], [2, 指定の文字列+2, 2人目の得点データ]・・・`

こうすれば、`pdf_data`配列の中の1人分のデータの要素数が13になるので、残りの2列分も書き出されるようになると考えました。

```ruby
pdf_data = pdf_data.map.with_index do |subject_data, i|
  subject_data.unshift(i)
  subject_data.insert(1, "CHIBA#{i}")
end
    
pdf_data.each_with_index do |subject_data, subject_i|
  subject_num = subject_i + 1
  subject_data.each_with_index do |score, score_i|
    worksheet.add_cell(subject_num, score_i, score)
  end
end
```

```
[[0, "CHIBA0", "4", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "1", "3", "3", "23"],
 [1, "CHIBA1", "5", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "2", "5", "3", "27"]]
```

### 別のメソッドでバグが発生
`pdf_data`は別のメソッドに渡してそこでも使っていたため、別のメソッドでバグが生じました。

その結果、このように一致すべき値がズレて表示されてしまいました。
![スクリーンショット 2024-10-20 午後4.34.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/0e8bee7c-27d6-ba00-c820-34b166046403.png)

## 試したこと②
`map`メソッドで配列を元の配列自体を変更するのではなく、Railsの`deep_dup`メソッドで複製しました。

`dup`メソッドでの浅いコピーだと変わりませんでした。
![スクリーンショット 2024-10-20 午後4.59.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/e14575a9-0338-1210-b0cb-bd66b6bd3e40.png)

## 変更後のコード
```ruby
pdf_scores_with_id = pdf_data.deep_dup

pdf_scores_with_id.map.with_index do |subject_data, i|
  subject_data.unshift(i)
  subject_data.insert(1, "CHIBA#{i}")
end

pdf_scores_with_id.each_with_index do |subject_data, subject_i|
  subject_num = subject_i + 1
  subject_data.each_with_index do |score, score_i|
    worksheet.add_cell(subject_num, score_i, score)
  end
end
```

## 最後に
変数がデータを示すのは当たり前なので、`pdf_data`という変数名は良くないと思いました。`pdf_scores`に修正します。