Ruby on Railsのディレクトリ構成とファイルの役割 | チュートリアル学びまとめ

# はじめに
[Ruby on Rails チュートリアル 第7版](https://railstutorial.jp/chapters/beginning?version=7.0)を完走したので、そこで学んだことをまとめていきます！
筆者はチュートリアル以外にRailsの経験は無いので、記事に書くことはチュートリアルに基づく知識になりますがあしからず:bow:
使用したバージョンは以下になります。Gemfileについてはチュートリアルに完全なリストがあるので、そちらを参照してください👀

||バージョン|
|-:|:-:|
|ruby|3.1.2|
|rails|7.0.4|
|bundler|2.3.14|

チュートリアルで触れたところ以外はざっと調べただけだったり、飛ばしたりしているので、ここも書いてないけど重要だよというところがあればぜひコメントでご指摘いただけると助かります:smiley_cat:

# ツリー
番号は下の役割と対応しています。
```
.
├── Gemfile // 1
├── Gemfile.lock // 2
├── README.md // 3
├── Rakefile // 4
├── app // 5
│   ├── assets // 5-1
│   │   ├── config
│   │   │   └── manifest.js
│   │   ├── images
│   │   │   ├── ...
│   │   │   ...
│   │   └── stylesheets
│   │       ├── application.css
│   │       ...
│   ├── channels // 5-2
│   │   └── application_cable
│   │       ├── channel.rb
│   │       └── connection.rb
│   ├── controllers // 5-3
│   │   ├── application_controller.rb
│   │   ├── concerns
│   │   ├── [コントローラ名]_controller.rb
│   │   ...
│   ├── helpers // 5-4
│   │   ├── application_helper.rb
│   │   ├── [ヘルパー名]_helper.rb
│   │   ...
│   ├── javascript // 5-5
│   │   ├── application.js
│   │   ├── controllers
│   │   │   ├── application.js
│   │   │   ├── hello_controller.js
│   │   │   └── index.js
│   │   └── custom
│   │       ├── ...
│   │       ...
│   ├── jobs // 5-6
│   │   └── application_job.rb
│   ├── mailers // 5-7
│   │   ├── application_mailer.rb
│   │   ├── [メーラー名]_mailer.rb
│   │   ...
│   ├── models // 5-8
│   │   ├── application_record.rb
│   │   ├── concerns
│   │   ├── [モデル名].rb
│   │   ...
│   └── views // 5-9
│       ├── layouts
│       │   ├── application.html.erb
│       │   ├── mailer.html.erb
│       │   ├── mailer.text.erb
│       │   ...
│       ...
├── bin // 6
│   ├── importmap
│   ├── rails
│   ├── rake
│   ├── render-build.sh
│   └── setup
├── config // 7
│   ├── application.rb // 7-1
│   ├── boot.rb
│   ├── cable.yml
│   ├── credentials.yml.enc // 7-2
│   ├── database.yml // 7-3
│   ├── environment.rb
│   ├── environments // 7-4
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── importmap.rb
│   ├── initializers // 7-5
│   │   ├── assets.rb
│   │   ├── content_security_policy.rb
│   │   ├── filter_parameter_logging.rb
│   │   ├── inflections.rb
│   │   └── permissions_policy.rb
│   ├── locales // 7-6
│   │   └── en.yml
│   ├── master.key // 7-7
│   ├── puma.rb // 7-8
│   ├── routes.rb // 7-9
│   └── storage.yml
├── config.ru // 8
├── db // 9
│   ├── migrate // 9-1
│   │   ├── ...
│   │   ...
│   ├── schema.rb // 9-2
│   └── seeds.rb // 9-3
├── lib // 10
│   ├── assets
│   └── tasks
├── log // 11
│   ├── development.log
│   └── test.log
├── public // 12
│   ├── 404.html
│   ├── 422.html
│   ├── 500.html
│   ├── apple-touch-icon-precomposed.png
│   ├── apple-touch-icon.png
│   ├── favicon.ico
│   └── robots.txt
├── storage // 13
│   ├── ...
│   ...
├── test // 14
│   ├── application_system_test_case.rb
│   ├── channels
│   │   └── application_cable
│   │       └── connection_test.rb
│   ├── controllers // 14-1
│   │   ├── [コントローラ名]_controller_test.rb
│   │   ...
│   ├── fixtures // 14-2
│   │   ├── files
│   │   │   ├── ...
│   │   │   ...
│   │   ├── [モデル名].yml
│   │   ...
│   ├── helpers // 14-3
│   │   ├── application_helper_test.rb
│   │   ├── [ヘルパー名]_helper_test.rb
│   │   ...
│   ├── integration // 14-4
│   │   ├── [テスト名]_test.rb
│   │   ...
│   ├── mailers // 14-5
│   │   ├── previews
│   │   │   ├── [メーラー名]_mailer_preview.rb
│   │   │   ...
│   │   ├── [メーラー名]_mailer_test.rb
│   │   ...
│   ├── models // 14-6
│   │   ├── [モデル名]_test.rb
│   │   ...
│   ├── system // 14-7
│   └── test_helper.rb // 14-8
├── tmp // 15
│   ├── cache
│   │   ├── assets
│   │   │   └── sprockets
│   │   │       └── v4.0.0
│   │   │           ├── ...
│   │   │           ...
│   │   └── bootsnap
│   │       ├── compile-cache-iseq
│   │       │   ├── ...
│   │       ... ...
│   │       ├── compile-cache-yaml
│   │       │   ├── ...
│   │       ... ...
│   │       └── load-path-cache
│   ├── development_secret.txt
│   ├── pids
│   │   └── server.pid
│   ├── restart.txt
│   ├── sockets
│   └── storage
│       ├── ...
│       ...
└── vendor // 16
    └── javascript
```

# 役割

全般的な参考：

https://railsdoc.com/rails_base

## 1. `Gemfile`
Gemというパッケージマネージャで依存関係を指定できるファイル。
チュートリアルでは、`will_paginate`や`faker`、`bcrypt`など様々なパッケージを取り込んだ。
環境ごとに必要なパッケージを指定できる(テスティングフレームワークはテスト環境だけに入れるとか)。
バージョン指定も、常に最新/マイナーバージョンアップは許す/固定などできる。

参考：

https://railstutorial.jp/chapters/beginning?version=7.0#sec-bundler

## 2. `Gemfile.lock`
Gemfileから実際にインストールされたGemの一覧とバージョン。
`bundle install`コマンドによって生成される。
プラットフォームの情報が書いてあったりもする。チュートリアルでは、`bundle lock --add-platform x86_64-linux`コマンドによって追加した。ローカルでlinux以外の環境を使っていて、本番はlinux環境である場合、このコマンドを実行しておかないと、ローカルでは動くが本番では動かない現象が起きた。

## 3. `README.md`
作ったアプリケーションの説明を記述するREADMEファイル。
動かし方とかライセンスとかアプリケーションの概要とか、必要な説明を書く。

## 4. `Rakefile`
RakeというRubyのビルドツール用のファイル。
チュートリアルでは触れなかったが、Makefileをrubyで書けるようにしたものという理解で良さそう。

参考：

https://docs.ruby-lang.org/ja/latest/library/rake.html

## 5. `app`
アプリケーション用のディレクトリ。主に触ることになるディレクトリその1(もう一つは`test`)。

### 5-1. `app/assets`
アプリケーション用のリソース(画像やスタイルシート)を置くディレクトリ。
アセットというと`javascript`も含まれるらしいが、そこだけは別のディレクトリ(`app/javascript`)に置かれる。
`app/assets/config/manifest.js`がアセット全体のマニフェストファイル、`app/assets/stylesheets/application.css`がスタイルシートのマニフェストファイルになっており、どのディレクトリにアセットが置かれているかが書かれている。
アセットはアセットパイプラインというフレームワークによって最小化または圧縮して連結される。画像の場合リネームされるようで、"jpeg"が"jpg"になって画像を読み込めないということがあった。デフォルトでは本番環境で有効になっており、サイト読み込みの高速化に寄与してくれるそうなので、無効にすることの無いように。

参考：

https://railstutorial.jp/chapters/filling_in_the_layout?version=7.0#sec-sass_and_the_asset_pipeline

https://railsguides.jp/asset_pipeline.html

https://www.wantedly.com/companies/wantedly/post_articles/354873

### 5-2. `app/channels`
Action Cableファイル用のディレクトリ。
チュートリアルで触ることはなかったが、アクションケーブル(Action Cable)とはWebSocket通信を実現するためのフレームワークらしい。
リアルタイム機能(チャットとかゲームとか)を実現するときに使うことになりそう。

参考：

https://railsdoc.com/action_cable

https://railsguides.jp/action_cable_overview.html

https://github.com/rails/actioncable-examples

### 5-3. `app/controllers`
コントローラ用のディレクトリ。リクエストを処理するコントローラがルーティング設定によって決定されると、コントローラはリクエストの意味を理解して適切な出力を行う役目を担う。`app/view`以下のテンプレートと結び付けられる。
チュートリアルでは、RESTの原則に従い`index, show, new, create, edit, update, destroy`や、静的なページを表示するためのhelp/about/concantと言ったアクションを定義した。アクションの前にユーザーがログインしていることや、リクエストが適切なユーザーのものかを確認するために、`before_action`も使った。すべてのコントローラは`ApplicationController`を継承しているため、共通処理を`ApplicationController`に持たり、セッションに関するヘルパーをimportした。
`$ rails generate controller 名前 [アクション名..] [オプション]`コマンドによってファイルを生成できる。手動でも生成はできるが、規約があるのでコマンドを使っておくのが無難。前述のコマンドによって、ルーティングの追加、ビュー/コントローラのテスト/ヘルパーの生成も同時に行われる。

参考：

https://railsdoc.com/controller

https://railsguides.jp/action_controller_overview.html

https://railsdoc.com/rails#rails_generate_controller

### 5-4. `app/helpers`
ヘルパー用のディレクトリ。ヘルパーファイルで定義されているメソッドは、デフォルトで自動的にすべてのビューで利用できる。ヘルパーは基本的にビューのためのものだが、明示的にimportすることでコントローラやモデルで使用することもできる。
チュートリアルでは、Gravatarの画像を表示するためのメソッドや、セッションに関するメソッドを定義した。

参考：

https://railstutorial.jp/chapters/sign_up?version=7.0#sec-a_gravatar_image

https://railstutorial.jp/chapters/basic_login?version=7.0#sec-a_working_log_in_method

### 5-5. `app/javascript`
JavaScript関連のスクリプト用のディレクトリ。
`app/javascript/application.js`がマニフェストファイルになっており、importするファイルを指定している。
チュートリアルでは、メニューの開閉と画像アップロードに関連するjsを記述して活用した。

### 5-6. `app/jobs`
Active Job用のディレクトリ。
チュートリアルで触れることはなかったが、Active Jobはジョブを宣言し、それによってバックエンドでさまざまな方法によるキュー操作を実行するためのフレームワークらしい。
いわゆるバッチ処理を行う際に使うことになりそう。

参考：

https://railsdoc.com/active_job

https://railsguides.jp/active_job_basics.html

### 5-7. `app/mailers`
Action Mailerファイル用のディレクトリ。Action Mailerを使うと、アプリケーションのメーラークラスやビューでメールを送信できる。コントローラと同様に、`app/view`以下のテンプレートと結び付けられる。
チュートリアルでは、アカウントを有効化する際とパスワードを再設定する際にメールを送信した。すべてのメーラが`ApplicationMailer`を継承しており、`ApplicationMailer`にはfromとレイアウトの指定をした。
`$ rails generate mailer 名前 [メソッド..] [オプション]`コマンドによってファイルを生成できる。手動でも生成はできるが、規約があるのでコマンドを使っておくのが無難。前述のコマンドによって、ビュー/メーラーのテスト/プレビュー用ファイルの生成も同時に行われる。

参考：

https://railsguides.jp/action_mailer_basics.html

https://railstutorial.jp/chapters/account_activation?version=7.0#cha-account_activation

https://railstutorial.jp/chapters/password_reset?version=7.0#cha-password_reset

https://railsdoc.com/rails#rails_generate_mailer

### 5-8. `app/models`
モデル用のディレクトリ。RailsではActive Recordパターンが採用されており、モデルそのものもActive Recordと呼ぶ。
チュートリアルでは、ユーザーやマイクロポスト、フォローのモデルを定義した。その他にも以下のことを行った。

- バリデーションによって各カラムに制約を課した
  - `presence`、`length`、`uniqueness`、`format`など
- `has_many`と`belongs_to`によってモデルの関係を定義した
  - `dependent: :destroy`でカスケードの設定ができる
  - `class_name`と`foreign_key`でモデル名と異なる関係を定義できる
- `before_save`と`before_create`によってアクション前の処理を定義した
  - メールアドレスの小文字化、有効化トークンの生成
- `attr_accessor`によって仮想のプロパティを生やした
  - パスワードと各種トークン、暗号化する必要があるものに対して使った
- `has_secure_password`によってユーザーモデルにパスワードを持たせた
- モデル操作のためのメソッドをいくつも定義した
  - トークンをリセットする、メールを送る、期限切れ確認、フィードのクエリなど

`$ rails generate model 名前 [カラム名:型[:index]..] [オプション]`コマンドによってファイルを生成できる。手動でも生成はできるが、規約があるのでコマンドを使っておくのが無難。前述のコマンドによって、マイグレーション/モデルのテスト/フィクスチャの生成も同時に行われる。

参考：

https://railsdoc.com/model

https://railsguides.jp/active_record_basics.html

https://railsguides.jp/active_record_validations.html

https://railsguides.jp/active_record_querying.html

https://railsdoc.com/rails#rails_generate_model

### 5-9. `app/views`
ビュー用のディレクトリ。ERBというHTMLなどの文章の中にRubyスクリプトを埋め込むための形式で書かれる。ビューはコントローラのインスタンス変数にアクセスできる。デフォルトではヘルパーで定義したメソッドがすべて使える。"_"で始まるファイルはパーシャルと呼ばれ、共通部品を定義することでいくつものビューで使い回せるようになる。
チュートリアルでは、ホーム画面やユーザー一覧、パスワードリセットメールなど様々なビューを作成した。`app/views/layouts/application.html.erb`はアプリケーションで共通のレイアウトであり、ヘッダーやフッターを置いたり、`<head>`の中身を書いた。同様に`app/views/layouts/mailer.(html|text).erb`はAction Mailerの共通レイアウトになっている。
ファイルはビューやメーラーを生成するコマンドで一緒に生成される他、個別で生成することも多い。

参考：

https://railsdoc.com/view

https://railsguides.jp/action_view_overview.html

https://railsguides.jp/layouts_and_rendering.html

https://railsguides.jp/form_helpers.html

## 6. `bin`
アプリケションを管理する様々なスクリプト用のディレクトリ。何度も実行することになる`$ rails`コマンドもここに入っている。
チュートリアルでは、renderでビルドコマンドに指定するためのファイルを用意した。
そのほか、`bin/setup`はアプリケーションの初期設定時に設定を自動化するためのコードの置き場所らしいので、整備しておくと便利かもしれない。

参考：

https://railsguides.jp/command_line.html

https://railstutorial.jp/chapters/modeling_users?version=7.0#sec-modeling_users_conclusion

## 7. `config`
アプリケーションの設定ファイル用のディレクトリ。

参考：

https://railsdoc.com/config

https://railsguides.jp/configuring.html

### 7-1. `config/application.rb`
すべての環境で共通の設定ファイル。
チュートリアルでは、画像のサイズに制約をかける設定を記述した。
設定できる項目はたくさんあるが、`config/environments`以下で環境ごとに書くことが多いように思う。

### 7-2. `config/credentials.yml.enc`
機密情報を記載するファイル。暗号化されている。
デフォルトでアプリケーションの`secret_key_base`が含まれ、外部API向けのアクセスキーなどのcredentialも追加できるらしい。
暗号化されているのでGitHubなどで共有することができるようになり、以前に比べて手間が減ったそうな。

参考：

https://railsguides.jp/security.html#%E5%88%A9%E7%94%A8%E7%92%B0%E5%A2%83%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3

https://hirocorpblog.com/rails-credentials-master/

http://www.code-magagine.com/?p=7889

### 7-3. `config/database.yml`
データベースの設定ファイル。環境ごとに使うデータベースの種類や、URLの設定をする。

### 7-4. `config/environments`
環境単位の設定ファイル用のディレクトリ。項目はアセットに関するもの、ミドルウェアに関するもの、モデル/ビュー/コントローラに関するものなど実に様々。詳細は上記の参考ページを参照。

### 7-5. `config/initializers`
初期化ファイル用のディレクトリ。
チュートリアルで触れることはなかったが、フレームワークやgemがすべて読み込まれた後に行いたい設定（フレームワークやgemを設定するオプションなど）を保存できるらしい。

### 7-6. `config/locales`
国際化対応のためのリソースファイルを格納するディレクトリ。
チュートリアルで触れることはなかったが、辞書を作成しておき、`I18n`とやらを介して辞書にアクセスすることで、多言語対応できるらしい。

参考：

https://railsguides.jp/i18n.html

### 7-7. `config/master.key`
railsの秘密鍵。`$ rails new`でアプリケーションを作成した人が持っている。GitHubなどで**公開してはいけない**。デフォルトで`.gitignore`に指定されているので、わざわざいじることがなければ大丈夫。
`config/credentials.yml.enc`を暗号化/復号化するのに使用されているらしい。

参考：

https://railsguides.jp/security.html#%E5%88%A9%E7%94%A8%E7%92%B0%E5%A2%83%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3

https://hirocorpblog.com/rails-credentials-master/

http://www.code-magagine.com/?p=7889

### 7-8. `config/puma.rb`
webサーバーの設定ファイル。
チュートリアルでは、スレッド数やポート番号、pidfile置き場の設定を行った。

### 7-9. `config/routes.rb`
ルーティング定義ファイル。受け取ったURLを認識し、適切なコントローラ内アクションやRackアプリケーションに振り分ける。
チュートリアルでは、各種静的ページのルーティング、各リソースへのルーティングを定義した。ユーザーに対して`member`メソッドを使ってフォロー/フォロワーのルーティングを定義したり、リソースに対して`only:`を指定することで必要なルーティングだけを定義したりした。

参考：

https://railsguides.jp/routing.html

https://railsdoc.com/routes

## 8. `config.ru`
Rack用のファイル。Rackは、RubyのWebアプリケーションに対して、モジュール化された最小限のインターフェイスを提供して、インターフェイスを広範囲に使えるようにする。
チュートリアルで触れることはなかったが、`$ rails server`コマンドの代わりに`$ rackup config.ru`コマンドでサーバーを起動することもできるらしい。

参考：

https://railsguides.jp/rails_on_rack.html

https://github.com/rack/rack

https://zenn.dev/igaiga/books/rails-practice-note/viewer/rack_middleware_and_rack

https://techracho.bpsinc.jp/hachi8833/2022_08_02/77493

## 9. `db`
データベース関連のファイル用のディレクトリ。

### 9-1. `db/migrate`
マイグレーションファイル用のディレクトリ。`$ rails generate migration ...`または`$ rails generate model ...`コマンドによってファイルが生成される。
チュートリアルでは、テーブルの生成やカラムの追加、インデックスの追加で使用した。
`$ rails db:migrate`コマンドでマイグレーションが実行される。その他にも、ロールバックやリセットの際にもマイグレーションファイルが使用される。

参考：

https://railsdoc.com/migration

https://railsguides.jp/active_record_migrations.html

### 9-2. `db/schema.rb`
自動生成される現在のスキーマを表すファイル。マイグレーションやロールバックの度に更新される。

### 9-3. `db/seeds.rb`
初期データを生成するファイル。
チュートリアルでは、開発環境での動作確認用に、ユーザーやマイクロポストを生成した。
事前にDBをリセットした上で、`$ rails db:seed`コマンドでデータ生成が実行できる。

## 10. `lib`
複数のアプリケーション間で共有するライブラリ用のディレクトリ。
アプリケーションに関するファイルは`app`以下に置くので、それ以外の汎用的な処理があれば置いておくらしい。
チュートリアルで触れることはなかった。

参考：

https://qiita.com/necojackarc/items/fb76352dbea5bdd83366

https://www.slideshare.net/muryoimpl1/rails-37396344

## 11. `log`
ログファイル用のディレクトリ。環境ごとにログファイルが出力される。ログレベルというものがあり、環境ごとにレベルを設定できる。
チュートリアルで触れることはなかった。

参考：

https://railsguides.jp/debugging_rails_applications.html

## 12. `public`
Web上に公開するファイル用のディレクトリ。エラーページやクローラー向けファイルなどを含んでいる。
チュートリアルで触れることはなかった。

## 13. `storage`
ファイルのアップロードで保存されるディレクトリ。Active Storageなどを使ってファイルをアップロードしたときに、保存先がローカルディスクになっていると使用されるらしい。
チュートリアルで触れることはなかった。

参考：

https://railsguides.jp/active_storage_overview.html

## 14. `test`
アプリケーションのテストに使うファイル用のディレクトリ。主に触ることになるディレクトリその2。

参考：

https://railsdoc.com/test

https://railsguides.jp/testing.html

### 14-1. `test/controllers`
コントローラ(機能)テストのディレクトリ。`$ rails generate controller ...`コマンドでコントローラと一緒にファイルが生成される。
チュートリアルでは、特定のリスエスト後のステータスコード、リダイレクトされるか、モデルの数の変化、特定のタグが描画されているか、などのテストを書いた。

### 14-2. `test/fixtures`
テスト用のデータを生成するためのファイル。モデルごとにテストで使うデータをyamlで定義しておく。ここで定義されたデータは、例えばユーザモデルのmichaelを使いたいとすると、テスト中から`users(:michael)`とすることで呼び出すことができた。テストで使用する画像を置くこともできる。
チュートリアルでは、条件が異なる様々なデータを定義してテストに活用した。

### 14-3. `test/helpers`
ヘルパーテストのディレクトリ。
チュートリアルでは、主にセッションヘルパーに対してのテストを書いた。

### 14-4. `test/integration`
結合テストのディレクトリ。`$ rails generate integration_test 名前 [オプション]`コマンドでファイルを生成できる。
チュートリアルでは、サインアップやログイン、パスワードを再設定するといったフローの中で、適切なテンプレートが描画されているか、エラーや成功のflashが表示されているか、モデルが適切に生成/更新/削除されるか、などのテストを書いた。

### 14-5. `test/mailers`
メーラーテストのディレクトリ。`$ rails generate mailer ...`コマンドでメーラーと一緒にファイルが生成される。
チュートリアルでは、from/to/bodyが適切に生成されているかのテストを書いたほか、開発環境でメールレイアウトの確認をするためのプレビューファイルも作成した。

### 14-6. `test/models`
モデル(単体)テストのディレクトリ。`$ rails generate model ...`コマンドでモデルと一緒にファイルが生成される。
チュートリアルでは、バリデーションや特定のアクション前の処理が適切に動作しているか、関連付けられたモデルが一緒に削除されるか、モデル内で定義したメソッドの挙動、などのテストを書いた。

### 14-7. `test/system`
システムテストのディレクトリ。`$ rails generate system_test 名前 [オプション]`コマンドでファイルを生成できる。テストは、実際のブラウザまたはヘッドレスブラウザに対して実行されるらしい。
チュートリアルでは触れなかったが、ブラウザを使わないといけないテスト(主要導線の遷移とかかな)を書きたいときに使うことになりそう。

### 14-8. `test/test_helper.rb`
テスト用の便利メソッドを定義したり、テスティングのデフォルト設定を定義するファイル。
チュートリアルでは、ログイン関連のメソッドを定義したり、minitest-reportersの設定を書いた。

## 15. `tmp`
キャッシュなど、一時的なファイル用のディレクトリ。
チュートリアルで触れることはなかった。

## 16. `vendor`
外部ライブラリ用のディレクトリ。アセットが置かれることがあるらしい。
チュートリアルで触れることはなかった。

参考：

https://railsguides.jp/asset_pipeline.html

# 終わりに
アプリを初めて生成したときには大量のディレクトリとファイルに圧倒されましたが、記事にまとめることでかなり理解できた気がします:raised_hands:
この記事で扱ったものは基本的にデフォルトで生成されるものだけですが、実際のプロジェクトでは独自のディレクトリも作られたりするわけで、それらをどう整理するかも今後考えていきたいですね:muscle:(参考になりそうなページが合ったので下に置いておきます)

https://zenn.dev/takahashim/articles/ac725fb16ec7a11809c5