はじめに
Webアプリケーションフレームワーク「Ruby on Rails」は、この10月にバージョン7.1となりました。2021年12月にリリースされたバージョン7.0ではフロントエンド開発環境が大きく刷新されましたが、ほぼ2年ぶりとなる今回のバージョンアップでも、大型の機能追加や細かな改善が行われています。本連載では、強化・改善された機能から注目度の高いものをピックアップし、その概要を紹介します。
機能 | 概要 |
---|---|
デフォルトでDockerfileをサポート | 新規RailsアプリケーションでDockerfileが生成されるように |
Active Recordの非同期クエリの改善 | Active Recordで非同期クエリの拡張サポートが使用できるように |
Active Recordでの属性値の正規化 | normalizesで属性値に対して正規化を宣言できるように |
複合主キーをサポート | データベースとアプリケーションの両方で複合主キーがサポートされるように |
認証システム実装用メソッドの追加 | 特定目的でのトークン生成のためのgenerates_token_forメソッドが使用できるように |
非同期キュー機能の追加 | 大量のジョブを一度にエンキューするperform_all_laterメソッドが使用できるように |
自動読み込みの拡張メソッドの追加 | 自動読み込みを拡張するconfig.autoload_libメソッドとconfig.autoload_lib_once設定が使用できるように |
Trilogy用アダプターの導入 | MySQL互換DBクライアントであるTrilogyとRailsアプリケーションをシームレスに統合できるように |
JavaScriptランタイムBunのサポート | Node.jsに加えてBunも利用できるように |
新たなシリアライザのサポート | ActiveSupport::MessagePackが利用できるように |
テンプレートでの明示的なlocals | テンプレートに渡される変数を明確に制御できるように |
対象読者
- Railsの最新バージョンの機能を把握したい方
- Railsの経験者で、Railsに改めて入門したい方
- アプリケーションフレームワークの最新パラダイムに関心のある方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。
-
macOS Sonoma
- Ruby(3.2.2)
- Ruby on Rails(7.1.2)
- Visual Studio Code 1.84.0(Ruby LSP 0.4.13, Rails 0.17.8)
デフォルトでのDockerfileサポート
Rails 7.1では、新規アプリケーション作成時にデフォルトでDockerがサポートされるようになりました。
Dockerサポートの内容
Dockerとは、Docker社の開発する、コンテナ型仮想環境の開発、実行、配布を可能にするプラットフォームです。実行環境を開発環境とは別に用意し、立ち上げやデプロイを簡単に行えるので、アプリケーションの開発が効率化されるなどのメリットがあります。このDockerへのデプロイやアプリケーションのビルドがRailsでサポートされたことで、production環境をDockerコンテナで稼働させたいという場合に非常に便利になります。
Dockerサポートの内容は、まずはアプリケーションの作成時にDockerfileが生成されることです。Dockerfileは、Dockerコンテナの環境設定や必要なミドルウェアのインストールをコード化したもので、IaC(Infrastructure as Code)と呼ばれます。Dockerfileのおかげで、同じ環境の再現が容易になり、配布しやすく、再構築も気軽に行えるようになります。
以下は、既定で作成されるDockerfileの内容の一部です。
ARG RUBY_VERSION=3.2.2 FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base WORKDIR /rails ENV RAILS_ENV="production" \ BUNDLE_DEPLOYMENT="1" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WITHOUT="development" …略… RUN bundle install && \ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ bundle exec bootsnap precompile --gemfile …略… RUN bundle exec bootsnap precompile app/ lib/ …略… RUN apt-get update -qq && \ apt-get install --no-install-recommends -y curl libsqlite3-0 libvips && \ rm -rf /var/lib/apt/lists /var/cache/apt/archives …略… ENTRYPOINT ["/rails/bin/docker-entrypoint"] …略…
このDockerfileには、依存関係にあるコンポーネントのインストール、プリコンパイル、bin/docker-entrypointコマンドによるデータベースの初期化などが含まれており、本番環境で利用するために必要なものが準備されています。
Dockerコンテナにおける実行
ここで、Dockerの環境を準備して実際のデプロイを試してみます。本来であれば本番環境に多いLinuxをホストにすべきでしょうが、ここでは手元で試すということでmacOSに環境を用意することにします。「Install Docker Desktop on Mac | Docker Docs」からCPUアーキテクチャに合うパッケージDocker.dmgをダウンロードして、マウント後にDocker.appをアプリケーションフォルダにコピーしてください。
Windowsでは、「Install Docker Desktop on Windows | Docker Docs」からDocker Desktop Installer.exeをダウンロードしてインストールしてください。
以降は、macOSにおける説明です。
Docker.appを起動すると、「Docker Subscription Service Agreement」画面が表示されるので、[Accept]をクリックします。「Finish setting up Docker Desktop」画面になるので、[Use recommended settings (requires password)]を選択したままで[Finish]をクリックすれば初期設定は終了です(図1)。続けて起動する「Docker Desktop」は、今回は使用しないので閉じてしまって構いません。
次に、アプリケーションを作成します。内容は何でもよいので、投稿アプリのイメージでpost_appとしました。作成後、Scaffoldingによって適当なテーブルとコントローラーなどを作成します。この時点ではデータベースのマイグレーションは不要です。
% rails new post_app (プロジェクトを作成) % rails g scaffold post name:text (postsテーブルなどを作成)
production環境ではSSLでの接続を強制されるので、証明書などの準備と設定を省くために、非SSLでの接続ができるようにします。あくまでも動作検証のための変更ですので、本番環境では実施しないでください。
config.force_ssl = false # trueから修正
ここからはDockerの操作になります。
% docker build -t post_app . (カレントフォルダでタグ名post_appでビルド) % docker volume create app-storage (ボリュームapp-storageを作成) % docker run --rm -it -v app-storage:/rails/storage -p 3000:3000 --env RAILS_MASTER_KEY=`cat config/master.key` post_app (post_appをコンテナで実行) W, [2023-11-07T02:24:47.062897 #7] WARN -- : You are running SQLite in production, this is generally not recommended. You can disable this warning by setting "config.active_record.sqlite3_production_warning=false". I, [2023-11-07T02:24:47.096435 #7] INFO -- : Migrating to CreatePosts (20231107020320) == 20231107020320 CreatePosts: migrating ====================================== -- create_table(:posts) -> 0.0008s == 20231107020320 CreatePosts: migrated (0.0010s) ============================= => Booting Puma => Rails 7.1.1 application starting in production …略…
docker buildコマンドでは、-tオプションでタグ名post_appを指定して、カレントフォルダの内容でDockerイメージを作成しています。docker volume createコマンドでDockerボリュームapp-storageを作成し、docker runコマンドでイメージをボリュームにマウントし、実行します。なお、docker runコマンドで指定されているオプションは以下の通りとなります。
- --rm:実行終了後にコンテナをクリーンアップする
- -it:標準入出力(-i)とターミナル(-t)を有効にする
- -v:ボリュームのマウントポイントを指定する
- -p:コンテナ外部と内部のポートを接続する
- --env:環境変数を設定する
SQLiteはproduction環境では推奨されないこと、そしてエントリポイント(bin/docker-entrypoint)によるデータベースのマイグレーションが実行されている旨のメッセージが表示されています。
ここで、Webブラウザを起動してhttp://localhost:3000/postsにアクセスして、図2のように一覧画面とリンクが表示されれば成功です。
Railsのコンソールも、同様のコマンドで起動できるので便利です。オプションの内容は上記を参照してください。
% docker run --rm -it -v app-storage:/rails/storage --env RAILS_MASTER_KEY=`cat config/master.key` post_app console (コンテナでRailsコンソールを実行)