背景
rails new
する時に、「いらないファイル群を生成したくないな」と思い、rails new -J
でRailsアプリを作成したのですが、CRUDを実装している中で削除機能が実装できないという問題に直面しました。
なぜdelete
ができないかというと、以下のようにlink_to
ヘルパーで用意されている書き方にしたがって、リンクを踏んだ時にHTTPのDELTEリクエストが飛ばされるように記述したつもりでした。
<%= link_to 'Destroy', book, method: :delete, data: { confirm: 'Are you sure?' } %>
そもそもリンクを踏んだ時に飛ばされるリクエストはGETが基本であり、それ以外のリクエストを飛ばすためにオーバーライドをする必要があります。
しかし、この役割を担っているのがJavaScriptだと知らずにJavaScript関連ファイルの生成をスキップしてしまったため、このオーバーライドができず、結果として削除を行うことができなかったという経緯です。
そのため、今回はrails new -J
でJavaScript関連ファイルの生成をスキップしてしまった際に、後からJavaScriptを導入する方法についてまとめます。
環境
- Ruby 2.6.6
- Ruby on Rails 6.0.3.2
※rails new -J
でJavaScript関連のファイルが生成されていないRailsプロジェクトが作成されていることが前提で説明を進めていきます
実際の手順
webpackerのインストール
まずはwebpacker
をインストールする必要があります(webpackerについては後述)。
Gemfile
gem 'webpacker', '~> 4.0'
❯ bundle install
yarnのインストール
そして、Rails6では標準でyarnを用いてパッケージ管理をしているため、yarnをインストールしておく必要があります。 以下でyarnをインストールします(もうすでにyarnがインストールされている場合は飛ばして大丈夫です)。
❯ brew install yarn
JavaScript関連ファイルを生成
以下で、JavaScript関連ファイルをRailsプロジェクト内に生成します。
❯ bin/rails webpacker:install
上記により、以下のようなファイル群が生成されます。
.browserslistrc app/javascript/packs/application.js babel.config.js bin/webpack bin/webpack-dev-server config/webpack/development.js config/webpack/environment.js config/webpack/production.js config/webpack/test.js config/webpacker.yml package.json postcss.config.js yarn.lock
rails/ujs
をインストール
上記の、HTTPメソッドをオーバーライドするというのはrails/ujsというyarnパッケージが担っています(デフォルトでRailsに同梱されています)。そのため、以下でインストールします。
yarn add @rails/ujs
ViewでJavaScriptが適用されるように
インストールが終わったら下記のように記述を追加します。
app/javascript/packs/application.js
require("@rails/ujs").start()
app/views/layouts/application.html.erb
<%= javascript_pack_tag 'application' %>
上記により、HTTPのメソッドオーバーライドができて、無事に上記のlink_to
のコードで、削除を行うことができました。
もう少し深堀り
そもそもwebpackerとは?
webpackerを説明するためには、webpackを説明する必要があります。
webpackとは、JavaScriptやCSS、画像などのフロントエンド関連のデータを管理してくれるツールです。
- ファイルやライブラリ同士の依存性を自動的に解決できる。
- モジュール単位で細かく分割することができるので、見通しの良い構造にすることができる。
- コンパイル・圧縮などを行ってくれる。
などのことを行ってくれるようです。
このwebpackをラッパーしてRails用に作成されたwebpackerというライブラリがあり、Rails6では、このwebpackerが標準で搭載されています。