パーフェクトRuby on Rails輪読会のためのリポジトリ作成・設定手順 [Ruby on Rails]

こんにちは!もとひろです。
今回は、パーフェクトRuby on Rails輪読会のためのリポジトリ作成・設定手順を書きたいと思います。
現在第5章で現時点までは問題なく動作していますが、今後学習を進めて動作しなくなる場合には追記するようにしたいと思います。

輪読会で使用している書籍

パーフェクトRuby on Rails【増補改訂版】
輪読会についてはこちら→輪読会は参加しよう! - もとひろ blog

最終的に得たい結果

学習を滞りなく進めていくために…

  • GitHubリポジトリをみんなで共有して使いたい!
    その日ドライバーになった人が書籍に沿ってコードを実装しpush、次の人がそれをpullして…という風にしたい!

  • リポジトリの管理は章ごとにしたい!
    rails newする度にリポジトリを作るのはめんどくさい!(rails newが多い)

  • 誰がやっても問題なく rails s できるようにしたい!
    端末が異なることやバージョンが合わないgemの組み合わせ等、様々なエラーが出たのでそれに対する対策もしたい!

環境

輪読会で設定した環境

書籍のバージョンを考慮して、輪読会開始時に参加者でバージョンを決めました。

私の環境

手順

リポジトリ作成〜 rails new する前まで

1:GitHubリポジトリを作成する

GitHub上で[Your Repositories]を開き[new]ボタンを押して新規作成画面を開きます。
そこからリポジトリ名・説明を書いて[Create repository]をクリックします。
ひとまず空のリポジトリ完成!

2:VSCodeのターミナルでローカルリポジトリにクローンする

$ git clone リポジトリのURL(例: https://github.com/motohiro-mm/Perfect_Ruby_on_Rails_Ch5.git)

3:.gitignoreファイルを作成する

通常rails newすると.gitignoreファイルは.gitファイルとともにアプリケーション内に作成されます。
今回は章ごとのGit管理をしていきたいので、最初に.gitignoreファイルを作成しておきrails newする際にオプションをつけてGit関連ファイルを作成しないようにしていきます。
一番最初に作成することでリポジトリ内の一番上の層に.gitignoreファイルをおくことができます。
参考リンク:【Rails】Git管理せずにRails newしたい - 時々とおまわり

ファイルの内容は以下のようにします。

.gitignoreファイルの内容

# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
#   git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/*/.bundle

# Ignore the default SQLite database.
/*/db/*.sqlite3
/*/db/*.sqlite3-journal
/*/db/*.sqlite3-*

# Ignore all logfiles and tempfiles.
/*/log/*
/*/tmp/*
!/*/log/.keep
!/*/tmp/.keep

# Ignore pidfiles, but keep the directory.
/*/tmp/pids/*
!/*/tmp/pids/
!/*/tmp/pids/.keep

# Ignore uploaded files in development.
/*/storage/*
!/*/storage/.keep

/*/public/assets
.byebug_history

# Ignore master key for decrypting credentials and more.
/*/config/master.key

/*/public/packs
/*/public/packs-test
/*/node_modules
/*/yarn-error.log
yarn-debug.log*
.yarn-integrity


rails new時に作成される.gitignoreファイルとの違いは、元々階層指定されているファイル・ディレクトリをもう一段階層を下げて指定している所です。
ファイル・ディレクトリの先頭に/がついているものは、さらに/*を先頭に追加しています。
参考リンク:[Git] .gitignoreの仕様詳解 #Git - Qiita

rails new 〜 rails sまで

1:アプリケーションを作成する

$ rails new アプリケーション名 --skip-git
もしくは
$ rails new アプリケーション名 -G

Git関連ファイル作成をskipするオプションをつけます。
参考リンク:【Rails】Git管理せずにRails newしたい - 時々とおまわり

2:プラットフォームを追加する

$ bundle lock --add-platform ruby
(Linux以外でnewされた場合は以下も追加↓)
$ bundle lock --add-platform x86_64-linux

端末の違い(Mac,Intel,Linux等)やBundlerのバージョンの違いなどにより、Bundlerがうまく実行できない場合があるようです。
そのため、誰の環境でもBundlerが実行できるよう、プラットフォームを追加しています。
参考リンク:Understanding The Gemfile.lock File

3:Gemfileを書き換える

<変更>
gem 'webpacker', '~> 4.0'
↓
gem 'webpacker', '~> 5.0'

<追加>
gem 'net-http' 

最初に設定したRailsのバージョンでアプリケーションを作成すると、webpackerが4.0系になりその後rails sした際にエラーが出ます。そのためwebpackerを5.0系に変更しています。
参考リンク:Rails 'error Command "webpack" not found.'について #Rails - Qiita

また、このままだとwarningが数行出るので、net-httpというgemを追加しています。
参考リンク:Net::ProtocRetryErrorのエラーをなくすためにnet-httpのgemを追加する

4:Gemfileに沿ってgemをインストールする

$ bundle install

5:再度webpackerをインストールする

$ bundle exec rails webpacker:install

webpackerのインストールを再度実行しています。途中の質問は全てYにしてください。
参考リンク:Rails 'error Command "webpack" not found.'について #Rails - Qiita

6:足りないパッケージを追加する

結論を先に言うと、以下2つのパッケージをインストールします。

$ yarn add '@babel/plugin-proposal-private-methods'

$ yarn add '@babel/plugin-proposal-private-property-in-object'


手順5まで終わった時点でrails sしようとすると一応できるのですが、その後scaffoldして一覧画面を開こうとするとエラー1にぶつかります。
(今回はhttp://127.0.0.1:3000/tasksを開こうとして出たエラーです)

エラー1

Started GET "/tasks" for 127.0.0.1 at 2023-10-27 15:07:33 +0900
   (0.5ms)  SELECT sqlite_version(*)
   (0.5ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by TasksController#index as HTML
  Rendering tasks/index.html.erb within layouts/application
  Task Load (0.3ms)  SELECT "tasks".* FROM "tasks"
  ↳ app/views/tasks/index.html.erb:14
  Rendered tasks/index.html.erb within layouts/application (Duration: 6.7ms | Allocations: 1419)
[Webpacker] Compiling...
[Webpacker] Compilation failed:
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: Cannot find package '@babel/plugin-proposal-private-methods' imported from /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/babel-virtual-resolve-base.js
    at new NodeError (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:203:5)
    at packageResolve (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:873:9)
    at moduleResolve (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:902:20)
    at defaultResolve (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:985:15)
    at resolve (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:999:12)
    at tryImportMetaResolve (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/files/plugins.js:137:45)
    at resolveStandardizedNameForImport (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/files/plugins.js:159:19)
    at resolveStandardizedName (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/files/plugins.js:168:12)
    at loadPlugin (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/files/plugins.js:47:20)
    at loadPlugin.next (<anonymous>)
    at createDescriptor (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-descriptors.js:140:16)
    at createDescriptor.next (<anonymous>)
    at step (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:261:32)
    at evaluateAsync (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:291:5)
    at /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:44:11
    at Array.forEach (<anonymous>)
    at Function.async (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:43:15)
    at Function.all (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:216:13)
    at Generator.next (<anonymous>)
    at createDescriptors (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-descriptors.js:102:41)
    at createDescriptors.next (<anonymous>)
    at createPluginDescriptors (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-descriptors.js:99:17)
    at createPluginDescriptors.next (<anonymous>)
    at /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/gensync-utils/functional.js:21:23
    at Generator.next (<anonymous>)
    at mergeChainOpts (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-chain.js:350:34)
    at mergeChainOpts.next (<anonymous>)
    at chainWalker (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-chain.js:317:14)
    at chainWalker.next (<anonymous>)
    at loadFileChain (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-chain.js:192:24)
    at loadFileChain.next (<anonymous>)
    at buildRootChain (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/config-chain.js:78:27)
    at buildRootChain.next (<anonymous>)
    at loadPrivatePartialConfig (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/partial.js:72:62)
    at loadPrivatePartialConfig.next (<anonymous>)
    at loadPartialConfig (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/partial.js:115:25)
    at loadPartialConfig.next (<anonymous>)
    at step (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:269:25)
    at evaluateAsync (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:291:5)
    at /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:93:9
    at new Promise (<anonymous>)
    at async (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/gensync/index.js:92:14)
    at stopHiding - secret - don't use this - v1 (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/errors/rewrite-stack-trace.js:47:12)
    at loadPartialConfigAsync (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/index.js:34:85)
    at Object.<anonymous> (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/babel-loader/lib/index.js:126:26)
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/babel-loader/lib/index.js:3:103)
    at _next (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/babel-loader/lib/index.js:4:194)
    at /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/babel-loader/lib/index.js:4:364
    at new Promise (<anonymous>) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Node.js v18.17.1

Completed 500 Internal Server Error in 1564ms (ActiveRecord: 0.4ms | Allocations: 12417)


  
ActionView::Template::Error (Webpacker can't find application.js in /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
   unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
}
):
     6:     <%= csp_meta_tag %>
     7: 
     8:     <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     9:     <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    10:   </head>
    11: 
    12:   <body>
  
app/views/layouts/application.html.erb:9

エラーに従い足りないパッケージを追加するとエラー2が出ます。

エラー2

Started GET "/tasks" for 127.0.0.1 at 2023-10-27 14:58:26 +0900
   (0.4ms)  SELECT sqlite_version(*)
   (0.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by TasksController#index as HTML
  Rendering tasks/index.html.erb within layouts/application
  Task Load (0.9ms)  SELECT "tasks".* FROM "tasks"
  ↳ app/views/tasks/index.html.erb:14
  Rendered tasks/index.html.erb within layouts/application (Duration: 5.4ms | Allocations: 1419)
[Webpacker] Compiling...
[Webpacker] Compilation failed:
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: [BABEL]: --- PLACEHOLDER PACKAGE ---
This @babel/plugin-proposal-private-property-in-object version is not meant to
be imported. Something is importing
@babel/plugin-proposal-private-property-in-object without declaring it in its
dependencies (or devDependencies) in the package.json file.
Add "@babel/plugin-proposal-private-property-in-object" to your devDependencies
to work around this error. This will make this message go away.
 (While processing: /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/plugin-proposal-private-property-in-object/lib/index.js)
    at Object.<anonymous> (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/plugin-proposal-private-property-in-object/lib/index.js:28:7)
    at Module._compile (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/v8-compile-cache/v8-compile-cache.js:192:30)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at loadPartialConfigAsync (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/@babel/core/lib/config/index.js:34:85)
    at Object.<anonymous> (/Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/node_modules/babel-loader/lib/index.js:126:26)

Node.js v18.17.1

Completed 500 Internal Server Error in 1518ms (ActiveRecord: 1.0ms | Allocations: 26665)


  
ActionView::Template::Error (Webpacker can't find application.js in /Users/omisan/study/perfect-rails/Perfect_Ruby_on_Rails_Ch4/sample/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
   unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
}
):
     6:     <%= csp_meta_tag %>
     7: 
     8:     <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     9:     <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    10:   </head>
    11: 
    12:   <body>
  
app/views/layouts/application.html.erb:9

エラー2を解消するためにさらにもう1つパッケージをインストールします。
結果、先に書いた2つのパッケージを追加することで2つのエラーを解消することができます。

ちなみに 足りないパッケージを追加すると脆弱性を指摘するメッセージが出ます。

added 1 package, and audited 1035 packages in 1s

102 packages are looking for funding
  run `npm fund` for details

90 vulnerabilities (1 low, 77 moderate, 12 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

$ npm audit fix --forceで自動修正してくれるようですが、$ npm auditで確認するとできていない部分が多々ありました。
手動修正もできるようですが、輪読会の勉強からそれてしまうので、今回はこのまま進めていくことにしました。
参考リンク:npm パッケージのバージョンアップと脆弱性対応 – rinoguchi's techlog
参考リンク:【npm】パッケージの脆弱性対処(備忘録) #JavaScript - Qiita

やっとエラーなくrails sできるようになりました!

git push 〜 Collaboratorsの設定まで

1:リモートリポジトリにpushする

$ cd ..
$ git add .
$ git commit -m "rails new アプリケーション名"
$ git push origin main

アプリケーションのディレクトリにいるうちに$ git add .すると.gitignoreファイルがpushされないので注意してください。
(.がカレントディレクトリ以下のファイルを指し、それらをaddするためです。)
参考リンク:【Git】git add -Aとgit add .とgit add -uの違い - あまブログ

2:GitHubでCollaboratorsを設定する

作成者以外でリポジトリにpushしたりmergeしたり変更したりする権限を持つ人がCollaboratorsです。

GitHubで該当リポジトリのSettingsを開きます。
Collaborators → Manage access → [Add people]ボタンをクリック
追加したい人の名前等で検索し選択したら [Select a collaborator above] ボタンを押して追加します。
これで招待が送られ、その人が承認するとCollaboratorsに登録されます。

これで全部の設定が終了です!お疲れ様でした。

おわりに

かなり長くなってしまいました。
一度リポジトリを作成したらその後はアプリケーションを新規作成する際に「rails new 〜 rails sまで」の段取りのみ必要になります。
様々なエラーが出たので、エラーを読む勉強になりました!
参加者がクローンして手元で動作させる手順もいつか書けたら良いなぁと思っています。

感謝!!!!!

今回の記事作成にあたり、
一緒に調べてくださったsadanoraさん(のらブログ)、
再現を手伝ってくださったmoegiさん(moegi - Divka)、
本当に本当にありがとうございました!



終わります👋