├── .github └── workflows │ └── markdown_link_check.yml ├── CHANGELOG.md ├── README.md ├── docs ├── el-training.md ├── optional_issues.md └── topics.md ├── github_actions ├── .github │ └── workflows │ │ ├── lint.yml │ │ └── test.yml └── README.md └── rubocop ├── .elcop-rspec.yml ├── .elcop.yml ├── .rubocop.yml └── README.md /.github/workflows/markdown_link_check.yml: -------------------------------------------------------------------------------- 1 | name: Markdown Link Check 2 | 3 | on: 4 | schedule: 5 | - cron: '30 1 * * 1' # 毎週月曜日の1:30(UTC) -> 毎週月曜日の10:30(JST) 6 | workflow_dispatch: 7 | 8 | jobs: 9 | markdown-link-check: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Check out code 14 | uses: actions/checkout@v3 15 | 16 | - name: Setup Node.js 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: 18 20 | 21 | - name: Check links 22 | run: | 23 | npm install -g markdown-link-check 24 | find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check 25 | 26 | - name: Notify Slack 27 | if: ${{ failure() }} 28 | uses: 8398a7/action-slack@v3 29 | with: 30 | status: ${{ job.status }} 31 | text: ":x: Markdown link check failed. See the details at ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" 32 | author_name: Link Checker 33 | fields: repo,commit,action,eventName,ref,workflow,job,took 34 | env: 35 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [1.12.0] - 2023-06-29 4 | ### Added 5 | - カリキュラムにあるリンクの有効性をGitHub Actionsで定期的に確認する 6 | 7 | ## [1.11.1] - 2023-06-14 8 | ### Fixed 9 | - ドキュメント内のリンク切れを修正しました 10 | 11 | ## [1.11.0] - 2023-05-22 12 | 13 | ### Added 14 | - ステップ5: `README.md` に環境構築手順をまとめる項目を追加しました 15 | 16 | ### Changed 17 | - 概要: デプロイ先のサービスをRenderへ変更しました 18 | - ステップ4: 19 | - 図形描画ツールの案内を追加しました 20 | - 「テーブル図」という表現は一般的ではないので「ER図」に変更しました 21 | - ステップ6: 22 | - カリキュラムで使うRuboCopのおすすめ設定を変更しました 23 | - RuboCopがpush時に実行されるようにGitHub Actionsを設定するような記述を追加しました 24 | - 使用するCIをCircle CIからGitHub Actionsへ変更しました 25 | - ステップ7: Circle CIからGitHub Actionsに変更し、RSpecの結果をSlackに通知する設定を追加しました 26 | - ステップ10: RSpecの実行結果を通知する仕組みをCircle CIからGitHub Actionsへ変更しました 27 | - ステップ14: 28 | - デプロイ先をHerokuからRenderへ変更しました 29 | - Renderの使用方法や注意点を追加しました 30 | - ステップ16: 31 | - 検索機能の実装方法をRansackからFormオブジェクトを推奨するように変更しました 32 | - 検索とソートの組み合わせ表を作成するオプションを追加しました 33 | - ステップ17: デプロイ先のサービス変更に伴う記述の修正をしました 34 | 35 | ### Fixed 36 | - 不要な半角スペースの削除をしました 37 | 38 | ## [1.10.0] - 2022-03-29 39 | ### Added 40 | - ステップ8: SQLインジェクションについてサポーターに説明する課題を追加しました 41 | 42 | ### Changed 43 | - ステップ3: rails new する際に不要な機能を入れないようにレビューで確認・助言できるようにしたいので、このステップからPRを出すようにしました 44 | - ステップ4: 「モデル図」ではなく「テーブル図」を作っていただきたいので、「テーブル図」という表現に変更しました 45 | - ステップ4: 「モデル名・カラム名・データ型」という表現だと、これ以外の項目(制約や役割など)を考慮する余地を狭めてしまうので、文言を修正しました 46 | - ステップ4: README.md に記載したあとの指示が抜けているとそのまま main に push してしまう例も見られたのでレビューに出して貰うように明記しました 47 | - ステップ6: Circle CI の初期設定はサポーターが実施することを勧めるように明記しました 48 | - ステップ7: 「HTTPでどのようなやり取りが行われているかを把握すること」がこの設問の意図でしたが、「Railsのルーティングの仕組みについて把握すること」を意図だと思われてしまうことがことあったため、説明を修正しました 49 | - ステップ11: 想定しているロケールファイルの配置が行われやすくなるように文言を修正しました 50 | - ステップ14: デフォルトブランチ名を master から main に変更 51 | - ステップ14: Herokuアカウントの登録するときのメアドは会社・個人どちらでも良いことを明記しました 52 | 53 | ## [1.9.0] - 2021-02-25 54 | ### Added 55 | - ステップ6へRuboCopを導入するステップを追加しました 56 | 57 | ### Changed 58 | - RuboCopの導入がステップ6に入ったのに伴い、以降のステップ番号を整理しました 59 | - CIツールの導入について「Circle CIなど」と記載していた箇所を、「Circle CI」のみに改めました 60 | 61 | ### Fixed 62 | - 1.8.0 の CHANGELOG の表記内容を マンダリン語 -> マンダリン に修正 63 | 64 | ## [1.8.0] - 2020-01-29 65 | ### Added 66 | - 開発するアプリの背景について検討してもらうフェーズを追加しました 67 | 68 | ### Changed 69 | - メンター → サポーターに名称を変更しました 70 | - オプション要件を整理しました 71 | - バリデーション・DB制約を追加するステップを整理しました 72 | 73 | ### Fixed 74 | - マンダリン版の説明を修正しました 75 | 76 | ## [1.7.0] - 2019-02-06 77 | ### Added 78 | - 本カリキュラムの推奨図書として "現場で使える Ruby on Rails 5速習実践ガイド" を追加しました 79 | - オプション要件としてDockerによる開発環境の構築を追加しました 80 | - SQLへの理解度を測るステップを追加しました 81 | - Webアプリケーションへの理解度を測る項目を追加しました 82 | ### Changed 83 | - feature spec についての記載を system spec に変更しました 84 | - ステップ7の内容を複数のサブステップに分割しました 85 | - i18nを導入するステップの内容を明確化しました 86 | - N+1についての記載をより適切なステップへ移動しました 87 | ### Fixed 88 | - ステップ内の文章の語尾を統一しました 89 | - 表記揺れを統一しました 90 | 91 | ## [1.6.1] - 2018-06-06 92 | ### Changed 93 | - カリキュラム本文とトピックスのドキュメントを /docs 配下に移動しました 94 | - README.md に本リポジトリの紹介と他言語対応してくださったリポジトリのリンクを追記しました(Thanks! @jodeci) 95 | 96 | ## [1.6] - 2018-04-20 97 | ### Changed 98 | - ステップのタイトルをひと目見て何をするかを分かりやすくするため専門用語を削除しました 99 | - ステップのタイトルの語尾を統一しました 100 | - CI導入の優先度は高いとの判断の元、ステップ8の本文を一部変更しました 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # el-training 2 | 3 | 万葉で必須とされるRuby on Railsとその周辺技術の基礎を習得するための新入社員教育用カリキュラムです。 4 | 5 | ## ドキュメントの構成 6 | 7 | - [docs/el-training.md](https://github.com/everyleaf/el-training/blob/master/docs/el-training.md) 8 | - 新入社員教育用カリキュラムのドキュメントです 9 | - [docs/topics.md](https://github.com/everyleaf/el-training/blob/master/docs/topics.md) 10 | - カリキュラムに具体的には含まれていませんが、知ってほしいトピックをまとめたドキュメントです 11 | - [docs/optional_issues.md](https://github.com/everyleaf/el-training/blob/master/docs/optional_issues.md) 12 | - オプション課題をまとめたドキュメントです 13 | 14 | ## ライセンス 15 | 16 | このカリキュラムは[クリエイティブ・コモンズ 表示 - 非営利 - 継承 4.0 国際 ライセンス](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ja)の下に提供されています。 17 | 18 | [![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png)](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ja) 19 | 20 | ## Language Supports 21 | 22 | - マンダリン(繁體字:zh_TW) 23 | - https://github.com/5xruby/5xtraining (@jodeci 様ありがとうございます!) 24 | -------------------------------------------------------------------------------- /docs/el-training.md: -------------------------------------------------------------------------------- 1 | # el-training 2 | 3 | ## このカリキュラムについて 4 | 5 | この文書は、万葉で必須とされるRuby on Railsとその周辺技術の基礎を習得するための新入社員教育用カリキュラムです。 6 | 新入社員の能力によらず、必ず一通りのステップを実施していただきます。 7 | 研修期間は特に定めておりません。 8 | すべてのステップを完了した時点で研修修了となります。 9 | 10 | 本カリキュラムでは、以下の登場人物を想定しています。 11 | 12 | - 新入社員 : 本カリキュラムの受講者です。 13 | - サポーター : 新入社員の教育・指導・助言を行います。また、新入社員と相談して仕様を一緒に決めたりする役割も担います。 14 | 15 | 指導について、サポーターがどの程度関与するかどうかはサポーターの裁量に一任します。また、研修期間については、新入社員のスキルレベルや社内の案件状況を考慮して、サポーターの方であらかじめ目安を設定する予定です。 16 | 17 | ## 概要 18 | 19 | ### システムの要件 20 | 21 | 本カリキュラムでは、課題としてタスク管理システムを開発していただきます。 22 | タスク管理システムでは、以下のことを行いたいと考えています。 23 | 24 | - 自分のタスクを簡単に登録したい 25 | - タスクに終了期限を設定できるようにしたい 26 | - タスクに優先順位をつけたい 27 | - ステータス(未着手・着手・完了)を管理したい 28 | - ステータスでタスクを絞り込みたい 29 | - タスク名・タスクの説明文でタスクを検索したい 30 | - タスクを一覧したい。一覧画面で(優先順位、終了期限などを元にして)ソートしたい 31 | - タスクにラベルなどをつけて分類したい 32 | - ユーザ登録し、自分が登録したタスクだけを見られるようにしたい 33 | 34 | また、上記の要件を満たすにあたって、次のような管理機能がほしいと考えています。 35 | 36 | - ユーザの管理機能 37 | 38 | ### サポートブラウザ 39 | 40 | - サポートブラウザはmacOS/Chrome各最新版を想定しています 41 | 42 | ### アプリケーション(サーバ)の構成について 43 | 44 | 以下の言語・ミドルウェアを使って構築していただきたいです(いずれも最新の安定バージョン)。 45 | 46 | - Ruby 47 | - Ruby on Rails 48 | - PostgreSQL 49 | 50 | デプロイ先については以下を利用していただきたいです。 51 | 52 | - Render 53 | 54 | ※ 性能要求・セキュリティ要求は特に定めませんが、一般的な品質で作ってください。 55 | あまりにサイトのレスポンスが悪い場合は改善をしていただきます 56 | 57 | ## 本カリキュラムの最終目標 58 | 59 | 本カリキュラムの終了時点で、以下の項目を習得することを想定しています。 60 | 61 | - Railsを利用した基本的なWebアプリケーションの実装ができるようになること 62 | - Railsアプリケーションで一般的な環境を使ってアプリケーションを公開できること 63 | - 公開されたRailsアプリケーションに対して、機能の追加やデータのメンテナンスができること 64 | - GitHubでPRをしてマージする一連の流れを習得すること。また、それに必要なGitのコマンドを習得すること 65 | - 適切な粒度でコミットができること 66 | - 適切にPRの説明文が書けること 67 | - レビューに対する対応と修正が一通りできること 68 | - 不明な点を適切なタイミングでチームメンバーや関係者に(今回はサポーターになります)口頭やチャットなどで質問ができること 69 | 70 | ## 推奨図書 71 | 72 | 研修カリキュラムを進めるにあたって、以下の書籍を推奨図書としてオススメします。 73 | 74 | - [現場で使える Ruby on Rails 5速習実践ガイド](https://book.mynavi.jp/ec/products/detail/id=93905) 75 | 76 | 現場で使える Ruby on Rails 5速習実践ガイドでは、研修カリキュラムと同様にタスク管理システムを題材としています。 77 | そのため、本研修を進める上で参考になる点が多数あるかと思います。 78 | 79 | また、本研修ではカバーしきれなかった内容や、チーム開発の進め方についても解説されています。ぜひ参考にしてみてください。 80 | 81 | ## 技術情報を調べるための基本的なサイト 82 | 83 | 初めて使うメソッドなどについては、必ず下記のサイトで調べて進めるようにしましょう。 84 | 85 | - [オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/index.html) 86 | - [Ruby on Rails API(リファレンス)](https://api.rubyonrails.org/) 87 | - [Ruby on Rails Guides](https://guides.rubyonrails.org/) 88 | - [(日本語版)](https://railsguides.jp/) 89 | 90 | ## 開発に役立つトピック集 91 | 92 | 特定の課題ステップには含められませんでしたが、活用してほしいトピックについて topics.md にまとめています。カリキュラムを実施する上で、必要に応じて参照して活用してください。 93 | 94 | ## 課題ステップ 95 | 96 | ### ステップ1: Railsの開発環境を構築しよう 97 | 98 | #### 1-1: Rubyのインストール 99 | 100 | - [rbenv](https://github.com/rbenv/rbenv)を利用して最新バージョンのRubyをインストールしてください 101 | - `ruby -v` コマンドでRubyのバージョンが表示されることを確認してください 102 | 103 | #### 1-2: Railsのインストール 104 | 105 | - GemコマンドでRailsをインストールしましょう 106 | - 最新バージョンのRailsをインストールしてください 107 | - `rails -v` コマンドでRailsのバージョンが表示されることを確認してください 108 | 109 | #### 1-3: データベース(PostgreSQL)のインストール 110 | 111 | - 手元のOSでPostgreSQLをインストールしましょう 112 | - macOSの場合は `brew` などでインストールしてください 113 | 114 | ### ステップ2: GitHubにリポジトリを作成しよう 115 | 116 | - 手元にGitをインストールしましょう 117 | - macOSの場合は `brew` などでインストールしてください 118 | - `gitconfig` でユーザ名、メールアドレスを登録しましょう 119 | - アプリ名(=リポジトリ名)を考えましょう 120 | - リポジトリを作成しましょう 121 | - アカウントがない場合は取得しましょう 122 | - その上で空のリポジトリを作成しましょう 123 | - mac を使用している人は、間違ってGitに入れてしまわないように以下の設定を追加しておきましょう 124 | - ~/.config/git/ignore というテキストファイルを作り、以下を書き込みましょう 125 | - ``` 126 | .DS_Store 127 | ``` 128 | 129 | ### ステップ3: Railsプロジェクトを作成しよう 130 | 131 | #### main ブランチに最初のコミットを積む 132 | 133 | - `rails new` コマンドでアプリケーションに必要なディレクトリやファイルを作成しましょう 134 | - `rails new --help` でオプションを確認し、適切なオプションで作成しましょう 135 | - [Tailwind CSS](https://tailwindcss.com/) の導入を必須とします 136 | - DBは PostgreSQL を推奨としますが、サポーターと相談の上、他のDBを使うことも可能です 137 | - 以下のおすすめのオプションを参考にしてください 138 | - いろいろな機能を追加したい人向け: 139 | - `--css=tailwind --database=postgresql --skip-action-mailbox` 140 | - カリキュラムのことだけをすすめたい人向け: 141 | - `--css=tailwind --database=postgresql --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-job --skip-active-storage --skip-action-cable --skip-jbuilder` 142 | - `rails db:create` で、ローカル環境にデータベースを作り、`rails db:migrate` で `db/schema.rb` が生成されたことを確認しましょう 143 | - バージョンを明示するため、利用するRubyのバージョンを `Gemfile` に記載しましょう 144 | - 例) `ruby "3.4.1"` 145 | - アプリケーションディレクトリで `git status` を打ってみましょう 146 | - ローカルにリポジトリが作成されているのを確認できます 147 | - `git add .` で作成したファイルをgitのstageに追加しましょう 148 | - `git commit -m "initial commit"` などとして変更をコミットしましょう 149 | - `git remote add origin https://github.com/{GitHubアカウント名}/{リポジトリ名}.git` として、ステップ2で作成したリモートリポジトリをローカルのgitに`origin`という名前で登録しましょう 150 | - `git push origin main` でGitHubにpushしましょう 151 | - GitHubへ見に行って、ファイルが登録されていることを確認しましょう 152 | 153 | #### ブランチを切り README と docs を整える 154 | 155 | - main からブランチを切りましょう 156 | - ※ 以下、各ステップでも任意の区切りでブランチを切って作業を進め、PR (Pull Request) を出す形で研修を行なっていきます 157 | - ルートディレクトリにある README.md の内容を自分のアプリの内容に書き換えましょう 158 | - 研修中に参照しやすいように、ルートディレクトリに `docs` というディレクトリを作り、この文書ファイル(el-training.md)をコピーして配置しましょう 159 | - これらの変更をブランチに入れ、GitHub へ push し、PR を作成してレビューしてもらいましょう 160 | - 必要に応じて WIP(Work In Progress) で PR を出すようにしましょう。詳しくは[トピック集](https://github.com/everyleaf/el-training/blob/master/docs/topics.md#github-%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E3%83%88%E3%83%94%E3%83%83%E3%82%AF)を参照してください 161 | - コメントが付いたらその対応を行ってください。2人から approve されたら main ブランチにマージしましょう 162 | 163 | #### Depandabot の通知について 164 | 165 | GitHubが自動的に gem などのバージョンアップ等の PR を作ってくれる `dependabot` の機能については、トレイニーが自分で適切に判断しながらレビューをしてもらったり、PRを並列的に処理したりすることが難しいので、研修中は[オフにする](https://docs.github.com/ja/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates#disabling-dependabot-version-updates)ことも検討しましょう(研修を行う組織ごとのポリシーに応じて進めてください)。ファイル操作が必要になるため、新しく PR を作成して対応しましょう。 166 | 167 | ### ステップ4: 作りたいアプリケーションのイメージを考えよう 168 | 169 | - 設計を進める前に、どのようなアプリになるか完成イメージ(画面設計)をサポーターと一緒に考えてみましょう 170 | - 図形描画ツール([draw.io](https://drawio-app.com/)、[figma](https://www.figma.com/ja/) など) やペーパープロトタイピングを用いてプロトタイプを作成しましょう 171 | - また、このアプリがどのような形で利用されるか(インターネットに公開するのか、社内向けか、etc…)についても(サポーターと一緒に)考えてみましょう 172 | - システムの要件を読んで、必要なデータ構造を考えてみましょう 173 | - どのようなテーブルが必要そうか・各テーブル名・カラム名・データ型・制約など、スキーマを作る際に必要な情報を考えてみましょう 174 | - データ構造を考えたら、それをER図として書き起こしてみましょう 175 | - 完成したら、サポーターにレビューしてもらいましょう 176 | - サポーターにレビューしてもらった結果、問題なさそうであれば、リポジトリにER図を入れておきましょう(手書きの場合は撮影した画像を保存しましょう) 177 | - `README.md` にテーブルスキーマを記載してPRを作成し、レビューしてもらいましょう 178 | 179 | ※ 現時点で正解のER図を作成する必要はまだありません。現時点での想定として作ってみましょう(今後のステップで間違いと思ったら改修していくイメージです) 180 | 181 | ### ステップ5: データベースの接続設定(周辺設定)をしよう 182 | 183 | - Bundlerをインストールしましょう 184 | - `Gemfile` で `pg` (PostgreSQLのデータベースドライバ)をインストールしましょう 185 | - `database.yml` の設定をしましょう 186 | - `rails db:create` コマンドでデータベースの作成をしましょう 187 | - `rails db` コマンドでデータベースへの接続確認をしましょう 188 | - `README.md` にDBセットアップも含めた環境構築の手順をまとめましょう 189 | - GitHub上でPRを作成してレビューしてもらいましょう 190 | 191 | ### ステップ6: タスクモデルを作成しよう 192 | 193 | ここではモデルファイルを Rails の generator を使って自動作成しますが、その前に自動テストコードが自動生成されないようにします。(自動テストについてはステップ9で取り組みます。)config/application.rb に以下の設定を追加してください。 194 | 195 | ```ruby 196 | config.generators do |g| 197 | g.test_framework nil # TODO: RSpecを入れるまで生成されないようにしておく 198 | end 199 | ``` 200 | 201 | タスクを管理するためのCRUDを作成します。 202 | まずは名前と詳細だけが登録できるシンプルな構成で作りましょう。 203 | 204 | - `rails generate` コマンドでタスクのCRUDに必要なモデルクラスを作成しましょう 205 | - マイグレーションを作成し、これを用いてテーブルを作成しましょう 206 | - マイグレーションは1つ前の状態に戻せることを担保できていることが大切です! `redo` を流して確認する癖をつけましょう 207 | - DBの制約についても忘れず設定するようにしましょう 208 | - `rails c` コマンドでモデル経由でデータベースに接続できることを確認しましょう 209 | - この時に試しにActiveRecordでレコードを作成してみましょう 210 | - バリデーションを設定しましょう 211 | - どのカラムにどのバリデーションを追加したらよいか考えてみましょう 212 | - GitHub上でPRを作成してレビューしてもらいましょう 213 | 214 | ### ステップ7: タスクを閲覧・登録・更新・削除できるようにしよう 215 | 216 | ステップ7は7-1から7-4のサブステップに分かれています。 217 | 各ステップを順番に進めて、最終的にタスクの一覧画面、詳細画面、作成画面、編集画面、削除機能を作成することになります。 218 | 219 | サブステップに分けているのは、全部を1つの巨大なPRにすると開発もレビューも大変になってしまうからで、実案件でもこのように、小さくわけて開発することが普通になっています。 220 | 今後のステップでも、PRが大きくなりそうな場合は2つ以上に分けてPRを出せないか検討しましょう。 221 | 222 | なお、画面(ビュー)を作る際には適宜CSS(Tailwind CSS の class)を整えながら進めましょう。 223 | 224 | #### ステップ7-1: タスクの一覧画面、詳細画面を作成しましょう 225 | 226 | - ステップ6で作成したタスクを、一覧画面、詳細画面で表示できるようにしましょう 227 | - `rails generate` コマンドでコントローラとビューを作成しましょう 228 | - どのテンプレートエンジンを採用するかはサポーターと相談して決めましょう 229 | - コントローラとビューに必要な実装を追加しましょう 230 | - `routes.rb` を編集して、 `http://localhost:3000/` でタスクの一覧画面が表示されるようにしましょう 231 | - 一覧画面にアクセスする際、HTTPでどのようなやり取りが行われているかを調べ、サポーターに説明してみましょう 232 | 233 | #### ステップ7-2: タスクの作成画面、編集画面を作成しましょう 234 | 235 | - 画面上からタスクの作成や編集ができるようにしましょう 236 | - 作成、更新後はそれぞれflashメッセージを画面に表示させましょう 237 | - バリデーションエラーが発生した場合は、エラーメッセージを画面に表示させましょう 238 | - GitHub上でPRを作成してレビューしてもらいましょう 239 | 240 | #### ステップ7-3: タスクを削除できるようにしましょう 241 | 242 | - 作成したタスクを削除できるようにしましょう 243 | - 削除後はflashメッセージを画面に表示させましょう 244 | - GitHub上でPRを作成してレビューしてもらいましょう 245 | 246 | ##### 注意点 247 | Rails7以降、削除については次の2点が従来と書き方が変わっています。 248 | 249 | 1. 削除後のリダイレクト時に、redirect_to の引数に status: :see_other を指定する必要がある 250 | - ※see_otherをつけないと、削除の処理の一環としてリダイレクトしている意味になり、リダイレクト先に DELETEメソッドで飛んでしまいます。 251 | 1. 削除に限りませんが、画面でリンクなどをクリックしたときに確認ダイアログを簡単に出す仕組みをRailsが提供しており、この仕組みの呼び方が変わっています。Rails7以降は、次のように記述します。 252 | - > link_to "削除", ..., data { turbo_confirm: "...削除してよろしいですか?" } 253 | - ※ 上記のように書くと data-turbo-confirm 属性がつきます 254 | 255 | #### ステップ7-4: 追加したコードを振り返ってみよう 256 | 257 | - ステップ7-1〜7-3で追加したコードについて、サポーターに説明してみましょう 258 | - クラス、メソッド、変数について 259 | - 処理の流れについて 260 | 261 | ### ステップ8: SQLに触れてみよう 262 | 263 | - データベースを操作しましょう 264 | - `rails db` コマンドでデータベースに接続しましょう 265 | - SQLでタスクの閲覧、作成、更新、削除をしましょう 266 | - タスクの一覧画面にアクセスして、SQLのログが流れていることを確認しましょう 267 | - どのようなSQLが実行されているか、サポーターに説明してみましょう 268 | - ActiveRecordのメソッドでどういうSQLが実行されるか確認してみましょう 269 | - `rails c` で `find` や `where` などを実行してみましょう 270 | - 「SQLインジェクション」と「RailsでSQLインジェクションを起こさないための書き方」についてサポーターに説明してみましょう 271 | 272 | ### ステップ9: テストを書こう 273 | 274 | - [rspec](https://github.com/rspec/rspec-rails) を導入しましょう 275 | - ステップ6で config/application.rb に加えた変更を元に戻しましょう(test_framework の設定を消す) 276 | - specを書くための準備をしましょう 277 | - `spec/spec_helper.rb` 、 `spec/rails_helper.rb` を用意しましょう 278 | - model specをバリデーションに対して書いてみましょう 279 | - 実際はそれほどバリデーションのテストは書きませんが、model specへの理解を深めるためにやってみましょう 280 | - system specをタスク機能に対して書いてみましょう 281 | - RSpecの結果をSlackへ通知するようにGitHub Actionsに設定しましょう 282 | - サポーターが実施する形でも構いません 283 | - 設定の参考: https://github.com/everyleaf/el-training/tree/master/github_actions/.github/workflows/test.yml 284 | - 参考書籍:https://leanpub.com/everydayrailsrspec-jp 285 | 286 | ### ステップ10: アプリの日本語部分を共通化しよう 287 | 288 | - Railsのi18nの仕組みを利用して、モデル名・属性名やバリデーションエラーメッセージを日本語で表示できるようにしましょう 289 | - その際、[rails-i18が提供するロケールファイル](https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml) と独自に追加したモデルへのロケールファイルはわけて管理するようにしましょう 290 | 291 | ### ステップ11: Railsのタイムゾーンを設定しよう 292 | 293 | - Railsのタイムゾーンを日本(東京)に設定しましょう 294 | 295 | ### ステップ12: デプロイをしよう 296 | 297 | - mainブランチにシンプルなタスク管理システムができたので、デプロイしてみましょう。 298 | - [Render](https://render.com/)にデプロイを実施してみましょう 299 | - アカウントがなければ登録しましょう 300 | - 登録するときのメールアドレスは会社・個人どちらでも構いません 301 | - デプロイ方法は公式ドキュメントの『[Getting Started with Ruby on Rails on Render](https://render.com/docs/deploy-rails)』を参考にすると良いでしょう 302 | - デプロイ方法は『[Use render.yaml to Deploy](https://render.com/docs/deploy-rails#use-renderyaml-to-deploy)』と『[Deploy Manually](https://render.com/docs/deploy-rails#deploy-manually)』の2つがあります 303 | - 無料プランだと『[Deploy Manually](https://render.com/docs/deploy-rails#deploy-manually)』しか利用できませんので、こちらを参考にしましょう 304 | - デプロイされたRender上のアプリを触ってみましょう 305 | - Renderのアプリケーションはインターネットでどこでも参照できるので、公開してはまずい情報は載せないようにしましょう 306 | - Basic認証をこの時点でいれてもいいかもしれません 307 | - RenderはGitHubリポジトリに接続されるので、今後はmainブランチにPRがマージされたときに自動でデプロイされます 308 | - RenderのアプリケーションのURLなどの情報を `README.md` に記載しましょう 309 | - その際に、このアプリで使っているフレームワークのバージョン情報なども記載しておくとなおよいです 310 | - RenderのPostgreSQLは無料プランだと30日間しか利用できません。期限に注意して進めましょう 311 | 312 | ### ステップ13: インライン編集を追加しよう 313 | - 一覧画面でタスクごとに編集ボタン等を設け、それを押すと一覧の該当行が編集可能になり、その場で更新ボタンをおせば、更新ができて一覧にも反映されるようにしてみましょう 314 | - 7-2で作った編集機能(アクション、画面)はそのまま維持して、それとは別に [Turbo Frames](https://turbo.hotwired.dev/handbook/frames) ([日本語版](https://everyleaf.github.io/hotwire_ja/turbo/handbook/frames/)) を用いて、インライン用の編集・更新を作ってみましょう 315 | - 最終的に、重複するビューをできるだけパーシャルにまとめるようにしましょう 316 | - 注意:Turbo Frames を使って``の一部(``以下など)を更新することはできません。なぜなら、``タグが`
`と``の間などに入るとテーブルとしてうまく認識されないからです。そのため、このステップに取り組む際には、もともと画面で`
`タグをつかっていた場合には、タグ組みの見直しが必要になるかもしれません。 317 | - ヒント: このステップの前までで、登録画面・編集画面は共通化しているかもしれませんが、今回足すインライン編集も共通化しなければいけないという前提はありません。まずは新しく足すには何が必要かを考えて書いてみて、結果的に共通化できればするというスタンスで進めるとよいでしょう。 318 | 319 | ### ステップ14: 終了期限を追加しよう 320 | 321 | - タスクに対して、終了期限を登録できるようにしてみましょう 322 | - 一覧画面で、終了期限でソートできるようにしましょう 323 | - あわせて、作成日時でもソートできるようにしてみましょう 324 | - specを拡充しましょう 325 | - PRしてレビューをしてもらったら、リリースしてみましょう 326 | 327 | ### ステップ15: ステータスを追加して、検索できるようにしよう 328 | 329 | ※ この研修では練習のため Ransack を使用せず、Form オブジェクトをスクラッチから作ることを推奨します。ただし、Form Object にはじめて取り組む方は、[Form Object にはじめて取り組む方向けの進め方アドバイス](#form-object-にはじめて取り組む方向けの進め方アドバイス)を参考に進めてください。 330 | 331 | - ステータス(未着手・着手中・完了)を追加してみましょう 332 | - ActiveRecordの[enum](https://api.rubyonrails.org/classes/ActiveRecord/Enum.html)を利用してステータスを表現・管理してみましょう 333 | - 一覧画面でタスク名とステータスで検索ができるようにしましょう 334 | - 検索機能はFormオブジェクトを導入して実装してみましょう 335 | - 絞り込んだ際、ログを見て発行されるSQLの変化を確認してみましょう 336 | - 以降のステップでも必要に応じて確認する癖をつけましょう 337 | - 検索インデックスを貼りましょう 338 | - ある程度まとまったテストデータを用意して log/development.log を見ながら動作確認を行い、インデックスの追加により速度が改善されることを確認しましょう 339 | - インデックスは、検索条件(WHERE句)や結合(JOIN)、並び替え(ORDER BY)で頻繁に使われるカラムに貼ると、検索速度が大幅に向上しますが、更新が多いカラムや低選択性(値の種類が少ない)なカラムには向いていません。そのため、研修アプリに登場する中で、比較的インデックスを貼るのに適していると思われる終了期限を題材に練習をします 340 | - 【オプション】PostgreSQLの explain などを使用して、データベース側でのインデックス使用状況なども見てみましょう 341 | - 検索に対してmodel specを追加してみましょう(system specも拡充しておきましょう) 342 | - 【オプション】検索条件とソート条件のすべての組み合わせを表にまとめましょう 343 | - アプリ内の複雑な挙動を把握することが目的です 344 | - 以下はシンプルな事例の表です。まとめる際の参考にしてください 345 | - 事例:赤と白の旗があり、それぞれを1本ずつ上げ下げする 346 | 347 | | | 旗を上げる | 旗を下げる | 348 | |-----|------------|------------| 349 | | 赤の旗 | 赤の旗が上がっている | 赤の旗が下がっている | 350 | | 白の旗 | 白の旗が上がっている | 白の旗が下がっている | 351 | 352 | #### Form Object にはじめて取り組む方向けの進め方アドバイス 353 | 354 | Rails における Form Object とは、画面上にフォーム(inputフィールドなどの集合)として現れるようなデータのうち、モデルにうまく対応しないデータのクラスを作ってフォームと連動させるやり方、およびその作られたクラスのことを言います。Form Objectがあるとなぜ便利なのかを体験するために、 **最初は、検索条件やソートなどの条件を、独自にパラメータでアクションに送るというやり方で実装してみましょう。** このように実装すると、アクション側で個別のパラメータの値をみてモデルを扱うことになり、コードが散らかり、整理しづらいと感じると思います。その後でForm Object パターンを使う形にリファクタリング(コード改善)することで、「Form Object を使うとパラメータによる処理の違いをすっきり整理して書ける」というメリットを理解しやすくなると思います。 355 | 356 | ### ステップ16: 優先順位を設定しよう 357 | 358 | - タスクに対して、優先順位(高中低)を登録できるようにしましょう 359 | - 優先順位でソートできるようにしましょう 360 | - system specを拡充しましょう 361 | - PRしてレビューをしてもらったら、リリースしてみましょう(以降続けてください) 362 | 363 | ### ステップ17: ページネーションを追加しよう 364 | 365 | - [Pagy](https://github.com/ddnexus/pagy)というGemを使って一覧画面にページネーションを追加してみましょう 366 | 367 | ### ステップ18: ユーザモデルを作成しよう 368 | 369 | - ユーザモデルを作成してみましょう 370 | - 最初のユーザをseedで作成してみましょう 371 | - seedで作った最初のユーザとタスクが紐づくようにしましょう 372 | - 関連に対してインデックスを貼りましょう 373 | - ※ Renderにデプロイした際に、すでに登録されているタスクとユーザが紐づいているようにしてください(データメンテナンス) 374 | 375 | ### ステップ19: ログイン/ログアウト機能を実装しよう 376 | 377 | - 追加のGemを使わず、自分で実装してみましょう 378 | - DeviseなどのGemを使わないことで、HTTPのCookieやRailsにおけるSessionなどの仕組みについて理解を深めることが目的です 379 | - また、一般的な認証についての理解を深めることも目的にしています(パスワードの取り扱いについてなど) 380 | - ログイン画面を実装しましょう 381 | - ログインしていない場合は、タスク管理のページに遷移できないようにしましょう 382 | - タスクを作成したときに、タスクをログイン中のユーザに紐付けるようにしましょう 383 | - 自分が作成したタスクだけを表示するようにしましょう 384 | - ログアウト機能を実装しましょう 385 | 386 | ### ステップ20: ユーザの管理画面を実装しよう 387 | 388 | - 画面上に管理メニューを追加しましょう 389 | - 管理画面にはかならず `/admin` というURLを先頭につけるようにしましょう 390 | - `routes.rb` に追加する前に、あらかじめURLやルーティング名( `*_path` となる名前)を想定して設計してみましょう 391 | - ユーザ一覧・作成・更新・削除を実装しましょう 392 | - ユーザを削除したら、そのユーザが抱えているタスクを削除するようにしてみましょう 393 | - ユーザの一覧画面で、ユーザが持っているタスクの数を表示するようにしてみましょう 394 | - N+1問題を回避するための仕組みを取り入れましょう 395 | - ユーザが作成したタスクの一覧が見られるようにしてみましょう 396 | 397 | ### ステップ21: ユーザにロールを追加しよう 398 | 399 | - ユーザに管理ユーザと一般ユーザを区別するようにしてみましょう 400 | - 管理ユーザだけがユーザ管理画面にアクセスできるようにしてみましょう 401 | - 一般ユーザが管理画面にアクセスした場合、専用の例外を出してみましょう 402 | - 例外を補足して、適切にエラーページを表示しましょう(ステップ23で実施しても構いません) 403 | - ユーザ管理画面でロールを選択できるようにしましょう 404 | - 管理ユーザが1人もいなくならないように削除の制御をしましょう 405 | - モデルのコールバックを利用してみましょう 406 | - ※ Gemの使用・不使用は自由です 407 | 408 | ### ステップ22: タスクにラベルをつけられるようにしよう 409 | 410 | - タスクに複数のラベルをつけられるようにしてみましょう 411 | - つけたラベルで検索できるようにしてみましょう 412 | 413 | ### ステップ23: エラーページを適切に設定しよう 414 | 415 | - Railsが用意しているデフォルトのエラーページを自分が作った画面にしてみましょう 416 | - 状況に応じて、適切にエラーページを設定しましょう 417 | - ステータスコードの404ページと500ページの2種類の設定は少なくとも必須とします 418 | 419 | ## あとがき 420 | 421 | お疲れさまでした。 422 | あなたは教育カリキュラムを一通り完遂しました!! 423 | 424 | このカリキュラムでは触れきれませんでしたが、今後は以下のトピックなどが必要になると思うので、学習を進めていくとよいと思います(案件を通じて学ぶことも多いと思います)。 425 | 426 | - Webアプリケーションの基本的な理解を深める 427 | - HTTPとHTTPSに関する理解 428 | - Railsのもう少し進んだ使い方を習得する 429 | - STI 430 | - ロギング 431 | - 明示的なトランザクション 432 | - 非同期処理 433 | - アセットパイプライン(どちらかというとリリース系のトピック) 434 | - JavaScriptやCSSなどのフロントエンドに関するより高度な理解 435 | - データベースに対する理解を深める 436 | - SQL 437 | - よりパフォーマンスを重視したクエリの構築 438 | - インデックスの理解をより深める 439 | - サーバ環境に関するより多くの理解 440 | - Linux OS 441 | - Webサーバ(Nginx)の設定 442 | - アプリケーションサーバ(Unicorn)の設定 443 | - PostgreSQLに関する設定への理解 444 | - リリースに関するツールの理解 445 | - Capistrano 446 | - Ansible 447 | -------------------------------------------------------------------------------- /docs/optional_issues.md: -------------------------------------------------------------------------------- 1 | ## (番外編)オプション課題 2 | 3 | 必須要件とは別に、タスク管理システムに関するオプション課題を以下に示します。 4 | サポーターと相談しつつ必要に応じて実施してみてください。 5 | 6 | ### オプション課題1: 終了間近や期限の過ぎたタスクがあった場合、アラートを出したい 7 | 8 | - ログインした時点で、どこかに終了間近や期限の過ぎたタスクを表示してみましょう 9 | - 既読などが分かるようになるとよりよい 10 | 11 | ### オプション課題2: ユーザの間でタスクを共有できるようにしたい 12 | 13 | - 複数人で同じタスクを参照・編集できるようにしたい 14 | - 例:サポーターと新入社員でタスクを共有できること 15 | - 作成者を表示する 16 | 17 | ### オプション課題3: グループを設定できるようにしたい 18 | 19 | - オプション課題2の続き 20 | - グループを設定できるようにして、グループ内だけでタスクを参照できるようにしたい 21 | 22 | ### オプション課題4: タスクに添付ファイルをつけられるようにしたい 23 | 24 | - タスクに対して添付ファイルをつけられるようにしてみましょう 25 | - Herokuの場合はS3バケットにアップロードした添付ファイルを管理するようにします 26 | - 適切にGemを選別して利用してみましょう 27 | 28 | ### オプション課題5: ユーザにプロフィール画像を設定できるようにしてみましょう 29 | 30 | - ユーザがプロフィール画像を設定できるようにしましょう 31 | - アップロードした画像はアイコンとして使用するので、遅くならないようにサムネイル画像も作りたい 32 | - 適切にGemやライブラリを選別しましょう 33 | 34 | ### オプション課題6: タスクカレンダーの機能がほしい 35 | 36 | - 終了期限を可視化するために、カレンダーに終了期限別にタスクを表示するようにしてみましょう 37 | - ライブラリの使用・不使用は自由です 38 | 39 | ### オプション課題7: タスクをドラッグ&ドロップで並べ替えられるようにしたい 40 | 41 | - タスク一覧でタスクをドラッグ&ドロップして並べ替えできるようにしてみましょう 42 | 43 | ### オプション課題8: ラベルの使用頻度をグラフ化してみましょう 44 | 45 | - 統計情報を可視化するために、グラフを導入してみましょう 46 | - グラフの種類は見やすいものを提案してみましょう 47 | 48 | ### オプション課題9: 終了間近のタスクを作成ユーザ宛てにメール通知してみましょう 49 | 50 | - 終了間近のタスクがある場合、バックグラウンドでメール通知してみましょう 51 | - メール送信はクラウドサービスを利用します 52 | - HerokuならばSendGrid 53 | - AWSならばAmazon SESなど 54 | - 1日1回のバッチで送信するようにしてみましょう 55 | - HerokuならばHeroku Scheduler(アドオン) 56 | - AWSだったらcronを設定してみる 57 | 58 | ### オプション課題10: AWS にインスタンスを作って環境構築する 59 | 60 | - AWSに環境構築をしてデプロイしてみましょう 61 | - ミドルウェアはNginx+Unicornを推奨構成とします 62 | - EC2のインスタンス等はサーバ要件を参照してください 63 | 64 | ### オプション課題11: Dockerで開発環境を構築する 65 | 66 | - Dockerを利用して開発環境を構築してみましょう 67 | -------------------------------------------------------------------------------- /docs/topics.md: -------------------------------------------------------------------------------- 1 | # 開発・業務に役立つトピック集 2 | 3 | 本ドキュメントは、カリキュラムに具体的には含まれていませんが、知っておいてほしいトピックをまとめたものです。特定のステップに含めることができなかった話題はここにまとめておきます。 4 | 5 | ## git に関するトピック 6 | 7 | gitの詳しい解説については 8 | 9 | https://git-scm.com/book/ja/ 10 | 11 | こちらが役に立つので参照してください。 12 | 以下のトピックはそれを補足する形でよく使用されるケースを紹介します。 13 | 14 | ### git のハッシュ値について 15 | 16 | gitでは、1つのコミットについて、1つの(ほぼ)ユニークなハッシュ値が付加されます。 17 | これは `git log` コマンドを実行すると確認できます。 18 | 19 | ``` 20 | commit a1d859d085125016938a1c25862474a15973d740 (HEAD -> add_tips) 21 | Author: Yuuki Tanaka 22 | Date: Tue Feb 20 14:46:25 2018 +0900 23 | 24 | xxxx 25 | ``` 26 | 27 | `a1d859d...` というのがハッシュ値です。主に以下の用途などでよく使うので覚えておきましょう。 28 | 29 | * 手元のコミットの状態と、GitHubの作業ブランチ上のコミットの状態が一致しているか確認するときに、ハッシュ値をみて担保する 30 | * 別のブランチのコミットを一部拝借したい場合、 `git cherry-pick (ハッシュ値)` で特定のコミットを手元のブランチに持ってくる 31 | * 特定のコミットの状態に戻りたい場合 `git checkout (ハッシュ値)` を指定して戻る 32 | 33 | ### PRを出すときに master ブランチの最新の状態を取り込む 34 | 35 | Pull Request(PR)を出す前に、自分の作業ブランチに 36 | PRする先(研修では master ブランチ)の最新の状態を反映しておくのが一般的です。 37 | 38 | 自分が作業をしている間に他のブランチが master ブランチに取り込まれるのはよくあることで、 39 | その変更を取り込んでおかないと、コードがバッティングしていたり、お互いが影響しあったりしてアプリケーションの動作に影響があることがあります。 40 | 41 | 研修カリキュラム中でも、レビュー待ちの間に別のブランチで作業を進めるといったことがあり、同様のことが起こりうるので、そのときには master ブランチの最新の状態を作業ブランチに取り込む癖をつけましょう。 42 | 43 | 変更を取り込むには `git rebase` コマンド、もしくは `git merge` コマンドで実施します。 44 | 45 | `git rebase` コマンドを用いた場合の実施例 46 | 47 | ```sh 48 | $ git fetch origin 49 | $ git rebase origin/master # ※ コードがバッティングした場合コンフリクトが発生します 50 | ``` 51 | 52 | ### git rebase -i でコミットを整理する 53 | 54 | 開発中には様々な理由で、まとまった機能を実装する前に中途半端にコミットしなければならないことがあったり、コミットした後で、細かいミスに気づいて手直しをするといったことはよくあります。 55 | 56 | そういう時、gitのコミットログが細切れになり、非常に履歴がわかりづらいものになります。 57 | コミットをまとまった単位で整理しておくと、履歴が追いやすくなったり、cherry-pick がしやすかったり、レビューがしやすくなったりと良いことが多いので、PRを出す前に整理する癖をつけましょう。 58 | コミットを整理するには、`git rebase -i` コマンドを使います。 59 | 60 | `git rebase -i` コマンドを使うと、コミットの前後を入れ替えたり、複数のコミットを1つにすること(squash)ができます。例えば次のようなコミット履歴があるとします。 61 | 62 | - Aの機能を実装したコミット -- (1) 63 | - Bの機能を実装したコミット -- (2) 64 | - Aに些末なミスがあり修正したコミット -- (3) 65 | 66 | `git rebase -i` コマンドを利用するとコミットの前後を入れ替えられるので 67 | 68 | - Aの機能を実装したコミット -- (1) 69 | - Aに些末なミスがあり修正したコミット -- (3) 70 | - Bの機能を実装したコミット -- (2) 71 | 72 | と入れ替えられます。更に複数のコミットを1つにすることができるので 73 | 74 | - Aの機能を実装したコミット -- (1, 3) 75 | - Bの機能を実装したコミット -- (2) 76 | 77 | と整理することができます。 78 | 79 | ### git の便利なクライアントツール 80 | 81 | git の公式サイトに、コマンドを直接実行しなくてもよい便利な GUI ツール集があるので色々試してみると良いでしょう。 82 | 83 | https://git-scm.com/download/gui/mac 84 | 85 | ## GitHub に関するトピック 86 | 87 | ### WIP (Draft) で Pull Request を作成する 88 | 89 | PR (Pull Request) は、完成していないうちから作成することができます。GitHub では、料金プランが Team 以上であれば、このような未完成の PR を Draft PR として作ることができます。 90 | Free プランの場合は、通常の PR のタイトルに `[WIP]` をつけるなどして運用できます。(WIP = Work in Progress) 91 | 92 | WIP (Draft) でPRを出すことは次のような利点があります。 93 | 94 | - 他の開発者に進捗を示すことができる 95 | - 開発者の目に触れるところにコードを置くことで、意識の食い違いや実装コードのまずいところを早期に発見できる 96 | - WIP (Draft) のPRを見てもらいながら開発の相談ができる 97 | 98 | 実際の開発でもよく利用されるので、研修でもWIP (Draft) でPRを出すことを実践してみましょう。 99 | 100 | 機能が完成して正式なPRとするときに、WIP の場合は `[WIP]` をタイトルから外し、Draft の場合は Ready for review ボタンを押します。 101 | 102 | ### Pull Request の粒度について 103 | 104 | Pull Request (PR) を適切な粒度に保つことはコードレビューやプロジェクトの管理を効率的に行うために重要です。以下のような点に注意しましょう。 105 | 106 | - 単一の目的に集中されている: PR が単一の目的に集中しているとレビュワーはその変更がもたらす影響を把握しやすくなります。 107 | - レビューしやすいサイズである: PR の差分が大きくなりすぎるとレビューの難易度が上がり見落としやミスが発生しやすくなります。 108 | 109 | どちらも PR による修正内容を把握しやすくするために重要です。レビュー時だけでなく、例えば不具合発生時などに過去の変更を追跡したり原因を特定する際にも PR の粒度が適切であると便利です。 110 | 111 | 例えば以下のようなシナリオでは、最後に行っているような PR 分割の検討を行いましょう。 112 | 113 | 1. 何らかの機能追加のために開発を行い PR を作成した 114 | 1. コードフォーマットの修正を行いたかったので Rubocop による自動修正を行った 115 | 1. Rubocop の自動修正が元々の機能追加とは無関係のファイルにまで及び、PR 上の差分が大きくなった 116 | 1. フォーマット修正は機能開発で触れたコードの範囲内に留め、その他の修正分はフォーマット修正に焦点を当てた別 PR で対応する 117 | 118 | ## Rails の開発環境に関するトピック 119 | 120 | ### rails console を利用する 121 | 122 | Rails は自身のフレームワークの中に `rails console` という対話的な実行環境(REPL)が同梱されています。Ruby で言うところの irb ですが、 `rails console` では Rails の環境を読み込んだ上で実行できるため、Railsで開発を行う際は、こちらを主に使用します。 123 | 124 | 用途としては、実装した機能の確認が挙げられます。モデルにメソッドを追加した場合などは、ブラウザで挙動を確認するより、 `rails console` で確認したほうが効率が良いことがよくあります。 125 | 126 | Railsのアプリケーションツリーに移動して以下のように起動して使います。 127 | 128 | ```sh 129 | $ rails c 130 | ``` 131 | 132 | ### debug gem を利用する 133 | 134 | debug という Gem を利用すると、アプリケーションの実行中に好きな場所で対話的な実行環境(REPL)を開いて現在の変数の状態や実行結果を得たり、リモートデバッグができるようになります。 135 | 136 | 公式ドキュメント: https://github.com/ruby/debug/blob/master/README.md 137 | 138 | #### Railsにおけるインストール方法 139 | 140 | Gemfile に以下の一文を追加します。(開発時にだけ使用するため、development と test 環境でのみ導入します) 141 | 142 | ```Ruby 143 | group :development, :test do 144 | gem 'debug' 145 | end 146 | ``` 147 | 148 | `bundle install` コマンドを実行すると使えるようになります。 149 | 150 | #### 使用例 151 | 152 | 1. デバッグしたいファイル上でdebugを読み込みます。 153 | ```Ruby 154 | require 'debug' 155 | ``` 156 | 2. 状況を確認したい部分に次のように `binding.break` を記述します。 157 | ```Ruby 158 | def parse(str) 159 | binding.break 160 | str.split(',') 161 | end 162 | ``` 163 | 164 | アプリケーションを実行した時点で、 `binding.break` を記述した部分に処理が到達すると、そこで REPL が立ち上がるので、宣言済みの変数の中身を見たり、メソッドを実行したりできます。 165 | 166 | 167 | ### ローカルにある Gem の中身を見る 168 | 169 | 開発中にアプリケーションで使用している Gem の詳しい挙動を知る必要性があることはよくあります。 170 | その際には自分のマシンにインストールされた Gem を見たり、 171 | Gem の中で `binding.break` を記載して詳細なデータの流れを見たりして把握することが多いです。 172 | また、Gem のコードを読んで参考にすることで、コーディング能力を磨くのにも役に立つでしょう。 173 | 174 | bundler には、Gemfile で管理されている Gem を取り扱うのに便利なコマンドが幾つか提供されています。 175 | 176 | #### bundle show 177 | 178 | `bundle show` コマンドを使うと Gem が配置されている path が得られます。 179 | 180 | ```sh 181 | $ bundle show rails 182 | /Users/yuuki/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/rails-4.2.6 183 | ``` 184 | 185 | #### bundle open 186 | 187 | `bundle open` コマンドを使うと Gem を指定のエディタで開くことができます。 188 | 環境変数 `BUNDLER_EDITOR` でお使いのエディタを指定します。 189 | 190 | ```sh 191 | $ export BUNDLER_EDITOR=atom 192 | $ bundle open rails 193 | ``` 194 | 195 | ここから、詳しく見たいコードを精査したり、`binding.break` などでデバッグコードを入れて、挙動を詳しく見ることができます。 196 | 197 | #### gem pristine 198 | 199 | Gem の内部にデバッグコードを入れたとき、もとに戻し忘れることがよくあります。 200 | そんなときには `gem pristine` コマンドを使うとインストールした時点のコードに戻すことができます。 201 | 202 | ```sh 203 | $ gem pristine rails 204 | ``` 205 | 206 | 全ての Gem を戻したいときは次のコマンドを使います。 207 | 208 | ```sh 209 | $ gem pristine --all 210 | ``` 211 | 212 | `bundle pristine` コマンドを使うと Gemfile 内の Gem をもとの状態に戻せます。 213 | 214 | ```sh 215 | $ bundle pristine 216 | ``` 217 | -------------------------------------------------------------------------------- /github_actions/.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: 3 | push: 4 | branches: [ main ] 5 | pull_request: 6 | types: [ opened, synchronize, reopened ] 7 | 8 | jobs: 9 | lint: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - name: Set up Ruby 14 | uses: ruby/setup-ruby@v1 15 | with: 16 | ruby-version: '3.2.0' # 利用する Ruby のバージョンに書き換える 17 | bundler-cache: true 18 | - name: Run lint 19 | run: bundle exec rubocop 20 | - name: Notify Slack when job failed 21 | if: ${{ failure() }} 22 | uses: slackapi/slack-github-action@v2.0.0 23 | with: 24 | webhook: ${{ secrets.SLACK_WEBHOOK_URL }} 25 | webhook-type: incoming-webhook 26 | payload: | 27 | { 28 | "text": "Rubocop lint job failed. Check the details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" 29 | } 30 | timeout-minutes: 3 31 | -------------------------------------------------------------------------------- /github_actions/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | push: 4 | branches: [ main ] 5 | pull_request: 6 | types: [ opened, synchronize, reopened ] 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | services: 12 | db: 13 | image: postgres:14.4 14 | ports: 15 | - 5432:5432 16 | env: 17 | POSTGRES_PASSWORD: "${{ env.PGPASSWORD }}" 18 | options: >- 19 | --health-cmd pg_isready 20 | --health-interval 10s 21 | --health-timeout 5s 22 | --health-retries 5 23 | env: 24 | RAILS_ENV: test 25 | PGUSER: postgres 26 | PGPASSWORD: password 27 | PGHOST: 127.0.0.1 28 | steps: 29 | - name: Checkout code 30 | uses: actions/checkout@v4 31 | - name: Set up Ruby 32 | uses: ruby/setup-ruby@v1 33 | with: 34 | bundler-cache: true 35 | - name: DB create 36 | run: bin/rails db:create 37 | - name: DB migrate 38 | run: bin/rails db:migrate 39 | - name: Run test 40 | run: bundle exec rspec 41 | - name: Notify Slack when job failed 42 | if: ${{ failure() }} 43 | uses: slackapi/slack-github-action@v2.0.0 44 | with: 45 | webhook: ${{ secrets.SLACK_WEBHOOK_URL }} 46 | webhook-type: incoming-webhook 47 | payload: | 48 | { 49 | "text": "Test job failed. Check the details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" 50 | } 51 | timeout-minutes: 10 52 | -------------------------------------------------------------------------------- /github_actions/README.md: -------------------------------------------------------------------------------- 1 | ## 本研修カリキュラムのおすすめGitHub Actions設定の利用方法 2 | `.github` ディレクトリをアプリケーションのルートディレクトリ内にコピーしてください。 3 | このディレクトリには以下のファイルが入っています。 4 | 5 | - lint.yml 6 | - Rubocop実行用のActions 7 | - test.yml 8 | - RSpec実行用のActions 9 | -------------------------------------------------------------------------------- /rubocop/.elcop-rspec.yml: -------------------------------------------------------------------------------- 1 | # RuboCop 万葉標準設定(RSpec) 2 | # - 各Copごとの設定は、グループ別に、アルファベット順に記述してください。 3 | # 4 | # Copyright 株式会社万葉 5 | 6 | require: 7 | - rubocop-rspec 8 | 9 | RSpec/ContextWording: 10 | Enabled: false 11 | RSpec/ExampleLength: 12 | Enabled: false 13 | RSpec/InstanceVariable: 14 | Exclude: 15 | - 'spec/views/**/*' 16 | RSpec/MultipleExpectations: 17 | Enabled: false 18 | RSpec/MultipleMemoizedHelpers: 19 | Enabled: false 20 | RSpec/NestedGroups: 21 | Max: 5 22 | RSpec/ScatteredSetup: 23 | Enabled: false 24 | -------------------------------------------------------------------------------- /rubocop/.elcop.yml: -------------------------------------------------------------------------------- 1 | # RuboCop 万葉標準設定(Railsアプリ用) 2 | # - 各Copごとの設定は、グループ別に、アルファベット順に記述してください。 3 | # 4 | # Copyright 株式会社万葉 5 | 6 | require: 7 | - rubocop-rails 8 | 9 | AllCops: 10 | NewCops: enable 11 | Exclude: # 自動生成ファイルを除外する 12 | - 'Gemfile' 13 | - 'bin/*' 14 | - 'db/schema.rb' 15 | - 'config/puma.rb' 16 | - 'Rakefile' 17 | - 'vendor/**/*' 18 | 19 | Layout/AccessModifierIndentation: 20 | Enabled: false 21 | Layout/BeginEndAlignment: 22 | Enabled: false 23 | Layout/DotPosition: 24 | Enabled: false 25 | Layout/EndAlignment: 26 | Enabled: false 27 | Layout/ExtraSpacing: 28 | Exclude: 29 | - 'db/migrate/**/*' 30 | Layout/HashAlignment: 31 | Enabled: false 32 | Layout/LineContinuationLeadingSpace: 33 | Enabled: false 34 | Layout/LineLength: 35 | Max: 160 36 | Layout/SpaceBeforeFirstArg: 37 | Exclude: 38 | - 'db/migrate/**/*' 39 | Metrics/AbcSize: 40 | Enabled: false 41 | Metrics/BlockLength: 42 | Enabled: false 43 | Metrics/BlockNesting: 44 | Enabled: false 45 | Metrics/ClassLength: 46 | Enabled: false 47 | Metrics/CyclomaticComplexity: 48 | Enabled: false 49 | Metrics/MethodLength: 50 | Enabled: false 51 | Metrics/ModuleLength: 52 | Enabled: false 53 | Metrics/ParameterLists: 54 | Max: 7 55 | MaxOptionalParameters: 7 56 | Metrics/PerceivedComplexity: 57 | Enabled: false 58 | 59 | Naming/AccessorMethodName: 60 | Exclude: 61 | - 'app/controllers/**/*' 62 | Naming/PredicateName: 63 | NamePrefix: 64 | - is_ 65 | ForbiddenPrefixes: 66 | - is_ 67 | Style/GuardClause: 68 | Enabled: false 69 | Style/BlockDelimiters: 70 | Enabled: false 71 | Style/ClassAndModuleChildren: 72 | Enabled: false 73 | Style/ConditionalAssignment: 74 | Enabled: false 75 | Style/DoubleNegation: 76 | Enabled: false 77 | Style/Documentation: 78 | Enabled: false 79 | Style/EmptyElse: 80 | Enabled: false 81 | Style/EmptyMethod: 82 | Enabled: false 83 | Style/FetchEnvVar: 84 | Enabled: false 85 | Style/FrozenStringLiteralComment: 86 | Enabled: false 87 | Style/GlobalStdStream: 88 | Enabled: false 89 | Style/HashLikeCase: 90 | Enabled: false 91 | Style/HashSyntax: 92 | EnforcedShorthandSyntax: either 93 | Style/IfInsideElse: 94 | Enabled: false 95 | Style/IfUnlessModifier: 96 | Enabled: false 97 | Style/Lambda: 98 | Enabled: false 99 | Style/NegatedIf: 100 | Enabled: false 101 | Style/NumericPredicate: 102 | Enabled: false 103 | Style/OptionalBooleanParameter: 104 | Enabled: false 105 | Style/QuotedSymbols: 106 | Enabled: false 107 | Style/StringLiterals: 108 | Enabled: false 109 | Style/StringLiteralsInInterpolation: 110 | Enabled: false 111 | Style/SymbolArray: 112 | Enabled: false 113 | Style/TrailingCommaInArguments: 114 | Enabled: false 115 | Style/TrailingCommaInArrayLiteral: 116 | Enabled: false 117 | Style/TrailingCommaInHashLiteral: 118 | Enabled: false 119 | Style/ZeroLengthPredicate: 120 | Enabled: false 121 | Style/WordArray: 122 | Enabled: false 123 | 124 | # rubocop-rails 125 | Rails/ActiveRecordCallbacksOrder: 126 | Enabled: false 127 | Rails/Blank: 128 | UnlessPresent: false 129 | Rails/BulkChangeTable: 130 | Enabled: false 131 | Rails/Delegate: 132 | Enabled: false 133 | Rails/I18nLocaleTexts: 134 | Enabled: false 135 | Rails/LexicallyScopedActionFilter: 136 | Enabled: false 137 | Rails/NotNullColumn: 138 | Enabled: false 139 | Rails/SkipsModelValidations: 140 | Enabled: false 141 | Rails/WhereExists: 142 | Enabled: false 143 | -------------------------------------------------------------------------------- /rubocop/.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: 2 | - ./.elcop.yml 3 | - ./.elcop-rspec.yml 4 | -------------------------------------------------------------------------------- /rubocop/README.md: -------------------------------------------------------------------------------- 1 | ## 本研修カリキュラムのおすすめRuboCop設定の利用方法 2 | [RuboCop](https://github.com/rubocop/rubocop)を導入して、 3 | 以下の3つのファイルを、アプリケーションのルートディレクトリ内にコピーしてください。 4 | 5 | - .rubocop.yml 6 | - .elcop.yml 7 | - .elcop-rspec.yml 8 | 9 | ご自分で設定をカスタマイズされる場合は、.rubocop.yml に記述します。 10 | .elcop.yml と .elcop-rspec.yml は、本研修カリキュラムの一部として更新される場合があります。 11 | 必要に応じて新しいバージョンに置き換えてご利用ください。 12 | 13 | ## RubocopのSuggestionについて 14 | 研修を進めていくうちに`capybara`などのgemをインストールすることがあると思います。 15 | それぞれのgem専用に対応したcopがある場合、rubocop実行時に以下のようなメッセージでおすすめしてくれます。 16 | 17 | ``` 18 | Tip: Based on detected gems, the following RuboCop extension libraries might be helpful: 19 | * rubocop-capybara (https://rubygems.org/gems/rubocop-capybara) 20 | * rubocop-rspec_rails (https://rubygems.org/gems/rubocop-rspec_rails) 21 | 22 | You can opt out of this message by adding the following to your config (see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions for more options): 23 | AllCops: 24 | SuggestExtensions: false 25 | ``` 26 | 27 | ところがこのメッセージは、おすすめのcopを導入するまでずっと表示されてしまいます。本来の rubocop 実行結果に集中しづらくなるため、 28 | メッセージに書かれている通りに、`SuggestExtensions: false` を .rubocop.yml に追記しましょう。 29 | 30 | ```yml 31 | AllCops: 32 | SuggestExtensions: false 33 | ``` 34 | --------------------------------------------------------------------------------