【プログラミング初心者の学習方法】自走力を意識したgemの学び方、ReadMeの読み解き方

### はじめに

こんにちは、駆け出しWebエンジニアを目指して学習中の「さば🐟」[@saba7678pg](https://twitter.com/saba7678pg)と申します。

:::note warn
技術記事の練習も兼ねて、プログラミング勉強中の身で書かせていただきました。
引用元などの情報に注意しながら書かせていただきましたが、
至らぬ点・誤った知識等が記載されている可能性がございます。

何かございましたらお手数ですがご指摘いただけますと幸いです。
:::

### 今回の記事の対象者
- Ruby,Railsについて学習中
- 最低でもProgateは一通り終えている
- Google Chromeを使用している
- あると便利なChatGPT（本家、Bing等なんでも）


### 初学者のプログラミング勉強方法

今回はタイトルに「自走力」というキーワードを入れてあるように、
自分で調べる力を養いつつ技術を学ぶにはどうしたらよいのか、というテーマで、
**自分自身で実践してみながら**今回の記事を書いております。

勉強の仕方については人それぞれという部分もあるかと思いますので、
1つの方法として参考にしてみてください。
先輩エンジニアの皆さま、
方向性として間違っていたり、「こうしたらいいよ！」というご指摘・助言等ありましたら、コメントやX（Twitter）等でご指摘頂けますと幸いです。

### 学ぶgemの選定

Google検索やChatGPTを用いて「Rails7 gem」に加えて「おすすめ」や「初心者」「必須」というキーワードを組み合わせて適当に拾ってみました。
Qiita内でgemを検索するのもよいかもしれません。

参考リンク：
[【Rails7】個人的によく使うGemのまとめ【11選】](https://blog.to-ko-s.com/recomended-gems/)
[Railsで個人的によく使うgemをまとめる](https://zenn.dev/mochiblock/articles/89f8bf248b1bd8)

今回は **[gem bullet](https://github.com/flyerhzm/bullet)**　を学んでみようと思います。

### gem bulletってなに？

まずはどんなことができるgemなのかざっくり理解します。
いきなりReadMeを読むのはハードルが高いので、
まずChatGPTや他の方の技術記事を参考にイメージを掴むのでもよいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/f19ac1ac-ea09-b93b-2424-0b014edc52b6.png)

要約すると
> アプリのパフォーマンス向上のために設計されたgem,実行するクエリの数を減らすこと（N＋１問題）を目的としたgem

と返ってきました。

質問の仕方によってはザックリとしたgem導入方法や参考リンクも提示してくれます。

参考リンク：
[【Rails】N+1問題をアラート表示してくれるgem「bullet」を初心者向けにまとめてみた](https://techtechmedia.com/nplusone_query-bullet-rails/)

今回はメジャーなgemを選定したので、分かりやすい技術記事などが溢れています。
しかし、turbo-railsなど新しめの技術や使っている人が少ない技術などは情報が少ない、ということもあるようです。
一通り触った後でもいいので必ず一次情報（開発者のマニュアルや公式ドキュメント）も確認してみましょう。

### DeepL翻訳を導入する

とはいっても一次情報は英語で書いてあることが多く、それだけで読む気力が削がれませんか？
そんなあなたにGoogleChromeの拡張ツール、DeepL翻訳。

「DeepL翻訳」で検索するとChromeの拡張機能インストールのリンクが検索上位に出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/539deb3a-c6ae-87f9-8617-bc8816cdf0ad.png)

インストール方法は上記の「Chromeに追加」を押すだけ。
後は翻訳したい文言をドラッグするとDeepL翻訳のアイコンが出てくるので、
それをクリックすると翻訳結果を出力してくれます。
（出てこない方はブラウザを再起動してみてください）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/8e04b4ed-764d-0d0d-36eb-e3f8819fe9be.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/9f06ea74-262d-cec4-90dc-cc0230762b60.png)

これでひとまずReadMeを読むことができるようになりました。

### Demoの記載を活用する

ReadMeによっては丁寧な解説で、「gemを用いたサンプルアプリでの使用例」を提示してくれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/9d7d1069-e887-bc7a-4143-52172b811f48.png)

今回のbulletはサンプルコードまで付いているので試しにやってみましょう。
その際、意図の分からないコードがある場合は闇雲に実行していくのではなく、
ChatGPTを活用して、コードがどういった処理をしているのか聞いてみるとより理解が深まります。

念の為いきなり操作に取り掛かるのではなく、
一通り翻訳を読んで全体の流れをザックリ掴んでおきましょう。

【ChatGPT使用例】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/2d89ad97-7599-ccea-5421-399ccc1513eb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/d178bca0-246d-da5b-f662-98de7d34d6bb.png)

こんな具合で、どのコードがどんな処理を行っているのか具体的に説明してくれます。

また、工程を行っている時に不明な点が出てきた場合も闇雲に操作せず、
どういった処理を求めてきているのか翻訳・確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/26a6b802-49a4-0f50-c1c8-14a9cc433222.png)

工程7まで一通り実装し、工程8：localhostへアクセスしたところ以下のポップアップが出てきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557068/e848e0fc-9a5a-eb12-003b-125859b73c5b.png)

工程8を翻訳すると以下のようなことが書いてありました。
> ブラウザで http://localhost:3000/posts にアクセスすると、次のようなポップアップ警告ボックスが表示される。
> これは、PostオブジェクトからCommentアソシエーションへのN+1クエリがあることを意味する。
> その間に、log/bullet.logファイルにログが追加されます。

``` log
# 実際にさばのローカル環境に出てきたログ
# これの意味合いについてもChatGPTを併用しどういった記述なのか読み解いていくのもよいかも。
2023-09-29 19:07:27[WARN] user: saba
GET /posts
USE eager loading detected
  Post => [:comments]
  Add to your query: .includes([:comments])
Call stack
  /Users/saba/test/test_bullet/app/views/posts/index.html.erb:9:in `map'
  /Users/saba/test/test_bullet/app/views/posts/index.html.erb:9:in `block in _app_views_posts_index_html_erb___2578743460871661074_23180'
  /Users/saba/test/test_bullet/app/views/posts/index.html.erb:6:in `_app_views_posts_index_html_erb___2578743460871661074_23180'
```

``` sql
# rails serber起動中にターミナルに出力されたログ
  Post Load (0.1ms)  SELECT "posts".* FROM "posts"
  ↳ app/views/posts/index.html.erb:6
  Comment Load (0.1ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ?  [["post_id", 1]]
  ↳ app/views/posts/index.html.erb:9:in `map'
  Comment Load (0.2ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ?  [["post_id", 2]]
  ↳ app/views/posts/index.html.erb:9:in `map'
```

工程9〜10を行ったところN＋1問題は解消され、アラートは出なくなり、SQLの処理数も減らすことができました。

``` sql
  Post Load (0.4ms)  SELECT "posts".* FROM "posts"
  ↳ app/views/posts/index.html.erb:6
  Comment Load (0.0ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" IN (?, ?)  [["post_id", 1], ["post_id", 2]]
  ↳ app/views/posts/index.html.erb:6
```

> N+1 query fixed. Cool! (公式のReadMeより引用)

工程11〜14にはN＋1問題が検出されたときに、
「どういった通知をしてくれるのか、どこに原因があるのか」という事例を紹介してくれているようです。

DeepL翻訳が読みにくい場合はChatGPTを併用し、
「初学者にも分かるよう、かみくだいて翻訳してください」
「上記について○○と解釈していますがあっていますか？」
などと質問してみるとより解釈が深まると思います。

:::note info
ReadMeに書かれていない場合、
GitHubのWikiに詳細が書かれている場合もあります。
:::


### 最後に

この他にも直接gemを構成するファイルを覗いてみる、```binding.pry```を書き加えてデバッグしながら動作を確認する、といった方法もあります。
上記についてまた改めて自身の経験と併せて記事を書く予定です。

プログラミングを学んでいる方の、勉強方法の1つとして参考になりましたら幸いです🐟