【初心者向け】bundler、Gemfile、Gemfile.lockの関係性について図でまとめてみた

Ruby on RailsでWebアプリケーション（以降ではRailsアプリと略します）を開発をするにあたり、gemの活用は開発効率をあげるために重要です。

Railsアプリ開発でgemを利用する機会は多くありますが、**どのようにgemが管理されているか**ということについて理解をする機会は少ないかもしれません。

今回は『bundler』『Gemfile』『Gemfile.lock』といった、**gemの管理を理解する上で重要な役割をもつ概念について紹介**をしたいと思います。

**2019年7月27日追記**
@scivola さんにコメントで補足説明をしていただきました。
非常に参考になる内容ですので、[こちらのコメント](https://qiita.com/nishina555/items/1b343d368c5ecec6aecf#comment-176603d546a8b5a937b3)もぜひ読んでいただければと思います。

## bundlerとは
『bundler』は依存関係にあるgemの依存関係やバージョンを管理してくれるgemです。

インストールしようとしているgem自身もほかのgemを利用しているケースがあります。その場合、依存関係にあるgemもあわせてインストールする必要があります。

また、各gemにはバージョンが設定されているのですが、同じgemでもバージョンが異なるとRailsアプリの挙動を変えてしまったり、他のgemに影響を与えてバグを発生させたりする可能性があります。

これらの問題を解決してくれるのがbundlerです。

**bundlerを利用することで『依存関係にあるgemの一括インストール』『gemのバージョン管理』ができるようになります。**



## Gemfileとは
『Gemfile』とはRailsアプリで利用するgemの一覧を管理するファイルです。

『bundlerによってインストールされるgemはどこで管理されているのか？』
それが今から紹介するGemfileの役割です。

`bundle install`というコマンドでgemをbundlerを利用してインストールするのですが、その際には**Gemfileに記載されているgemの一覧を参照し、まだインストールされていないgemがあればインストールを行います。**

ですので、Railsアプリで新しくgemを追加したいという場合はGemfileにgemの名前を追記していくことになります。

Gemfile、bundleコマンド、gemの関係性および処理の流れを図で表現すると以下のようになります。
![gemfile-overview-880.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/dfbd5ed8-c34f-c434-c5a7-41bcefa736d9.png)


## Gemfile.lockとは
『Gemfile.lock』はGemfileをもとに実際にインストールされたgemの一覧とバージョンが記載されたファイルです。

**Gemfile.lockには依存関係にあるgemも含め、bundlerによってインストールされた全てのgemとそのgemのバージョンが記載されています。**

Gemfile.lockはGemfileをもとにbundlerによってインストールされたgemの結果を出力するファイルです。そのため、基本的には手動で更新することはありません。
bundle installもしくはbundle updateをすることでGemfile.lockは自動で更新されます。

Railsアプリにインストールされたgemと、Gemfile.lockの関係性を図で表現すると以下のようになります。

![gemfilelock-overview-1024x780.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/d0b85ae9-4040-b3c6-cd1c-c4b4abba717b.png)



## GemfileとGemfile.lockの比較
GemfileとGemfile.lockの違いについて表にすると以下のようになります。

<table style="border-collapse: collapse; width: 100.103%; height: 132px;" border="1">
<tbody>
<tr style="height: 22px;">
<td style="width: 33.33%; height: 22px;"></td>
<td style="width: 33.33%; height: 22px; background-color: #e6e6e6; text-align: center;"><strong>Gemfile</strong></td>
<td style="width: 33.33%; height: 22px; background-color: #e6e6e6; text-align: center;"><strong>Gemfile.lock</strong></td>
</tr>
<tr style="height: 22px;">
<td style="background-color: #e6e6e6; text-align: center; width: 33.33%; height: 22px;"><strong>記載されているgem</strong></td>
<td style="width: 33.33%; height: 22px; text-align: center;">bundlerでインストールするgem</td>
<td style="width: 33.33%; height: 22px; text-align: center;">bundlerでインストールしたgem</td>
</tr>
<tr style="height: 22px;">
<td style="background-color: #e6e6e6; text-align: center; width: 33.33%; height: 22px;"><strong>更新タイミング</strong></td>
<td style="width: 33.33%; height: 22px; text-align: center;">bundleコマンド実行前</td>
<td style="width: 33.33%; height: 22px; text-align: center;">bundleコマンド実行後</td>
</tr>
<tr style="height: 22px;">
<td style="width: 33.33%; height: 22px; background-color: #e6e6e6; text-align: center;"><strong>更新方法</strong></td>
<td style="width: 33.33%; height: 22px; text-align: center;">手動更新</td>
<td style="width: 33.33%; height: 22px; text-align: center;">自動更新</td>
</tr>
</tbody>
</table>

『Gemfileの内容をもとにbundlerがgemをインストール → インストールしたgemの結果をGemfile.lockに記載』という一連の流れを図としてまとめると以下のようになります。

![bundle-gem-overview-880.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/bf222fcb-6e04-d239-f683-322b2aa817b4.png)


## さいごに
以上でRailsアプリにおける、bundler、Gemfile、Gemfile.lockの役割の紹介および図解を終わります。

詳細については<a href="https://nishinatoshiharu.com/fundamental-gem-knowledge/" target="_blank">『Gemfile?bundler?Rails開発するなら理解しておきたいgem管理の基礎知識』</a>で紹介していますので、興味のある方はご覧になってください。

ツイッター(<a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>)やってます。フォローしてもらえるとうれしいです！