Rails Engineを作成して、再利用可能なコンポーネントを開発する
はじめに
複数のRailsプロジェクトを管理していると、「この認証システム、別のプロジェクトでも使いたいな」「このブログ機能、コンポーネントとして切り出せないだろうか」といった状況に直面することがあります。このような課題を解決するための強力な仕組みがRails Engineです。
Rails Engineとは、一言で言えば「親アプリケーションに組み込むことができる、ミニチュア版のRailsアプリケーション」です。Engine自体がモデル、ビュー、コントローラ、ルーティングなどを持ち、独立した機能群を提供します。DeviseやForemといった多くの有名なgemも、実はRails Engineとして構築されています。
この記事では、簡単な「お知らせ」機能を持つRails Engineをゼロから作成し、それをホストとなるRailsアプリケーションに組み込むまでの手順を解説します。Engineの作成を通じて、Railsアプリケーションのモジュール化と再利用性を高める方法を学びましょう。
1. Engineの新規作成
まず、Railsのプラグインジェネレータを使って、Engineの雛形を作成します。--mountableオプションを付けるのがポイントです。
# Railsアプリケーションのディレクトリの外で実行
rails plugin new simple_announcer --mountable--mountable: このオプションを付けると、Engineが自身の名前空間で隔離された「マウント可能」なEngineとして作成されます。これにより、親アプリケーションのコードとの名前衝突を防ぐことができます。ブログ機能など、自己完結した機能をカプセル化する場合は、このオプションがほぼ必須です。
コマンドを実行すると、simple_announcerというディレクトリが作成されます。中身はapp, config, libなど、見慣れたRailsアプリケーションの構造によく似ています。
2. Engine内で機能を開発する
次に、作成したEngineのディレクトリに移動し、通常のRailsアプリケーションと同じように機能を開発していきます。ここでは、タイトルと本文を持つAnnouncementモデルをScaffoldで作成してみましょう。
cd simple_announcer
rails g scaffold Announcement title:string body:text published:booleanこれにより、Engine内にモデル、ビュー、コントローラ、マイグレーションが生成されます。
- モデル:
app/models/simple_announcer/announcement.rb - コントローラ:
app/controllers/simple_announcer/announcements_controller.rb - ビュー:
app/views/simple_announcer/announcements/
すべてのクラス名やモジュール名がSimpleAnnouncer::という名前空間でラップされ、親アプリケーションの同名のクラス(例えばAnnouncement)との衝突が避けられている点に注目してください。
Engineのルーティングファイルも自動で更新されます。
# simple_announcer/config/routes.rb
SimpleAnnouncer::Engine.routes.draw do
resources :announcements
end3. 親アプリケーションにEngineを組み込む
開発したEngineを、実際に利用する側のRailsアプリケーション(ホストアプリケーション)に組み込みます。
ステップ1: GemfileでEngineを指定
ホストアプリケーションのGemfileに、開発中のEngineをpathオプションで指定します。
# Gemfile
gem 'simple_announcer', path: '../simple_announcer'bundle installを実行して、Engineをインストールします。
ステップ2: Engineをマウント
ホストアプリケーションのルーティングファイル(config/routes.rb)を編集し、Engineを特定のエンドポイントに「マウント」します。
# config/routes.rb
Rails.application.routes.draw do
# ... 他のルート ...
# "/announcements" というパスに、SimpleAnnouncer Engineをマウントする
mount SimpleAnnouncer::Engine => "/announcements"
endこれにより、/announcements以下のURLへのリクエストが、SimpleAnnouncer Engineによって処理されるようになります。
ステップ3: マイグレーションの実行
Engineが持つデータベースのマイグレーションを、ホストアプリケーションにコピーして実行する必要があります。
まず、以下のコマンドでマイグレーションファイルをコピーします。
rails simple_announcer:install:migrationsこのコマンドは、Engineのdb/migrateディレクトリから、ホストアプリケーションのdb/migrateディレクトリにマイグレーションファイルをコピーします。
コピーが完了したら、通常通りマイグレーションを実行します。
rails db:migrateこれで、ホストアプリケーションのデータベースにsimple_announcer_announcementsテーブルが作成されます。
4. 動作確認
すべての設定が完了しました。ホストアプリケーションのサーバーを起動します。
rails serverブラウザで http://localhost:3000/announcements にアクセスしてみてください。Engineで作成したScaffoldの画面が表示され、お知らせの作成、表示、編集、削除ができるはずです。
この「お知らせ」機能は、完全に自己完結したコンポーネントとして、他のどのRailsアプリケーションにも同じ手順で簡単に組み込むことができます。
Engineのカスタマイズ
Rails Engineの強力な点の一つは、ホストアプリケーション側でEngineのビューやコントローラを簡単に上書き(オーバーライド)できることです。例えば、Engineが提供するお知らせ一覧ページのデザインを、ホストアプリケーションのレイアウトに合わせたい場合、ホストアプリケーション側のapp/views/simple_announcer/announcements/index.html.erbに新しいビューファイルを作成するだけで、Engineのデフォルトのビューが上書きされます。
まとめ
Rails Engineは、Railsアプリケーションのコードをモジュール化し、再利用性を高めるためのパワフルなツールです。
rails plugin new --mountableで再利用可能なEngineの雛形を作成する。- Engine内でモデル、ビュー、コントローラを開発する。
- ホストアプリケーションの
GemfileでEngineを読み込み、routes.rbでマウントする。 - Engineのマイグレーションをホストアプリケーションにコピーして実行する。
複数のアプリケーションで共通して利用する機能や、巨大なアプリケーションを機能単位で分割したい場合に、Rails Engineの導入は非常に有効な選択肢となります。独自の認証システムやCMS機能など、再利用可能なコンポーネントをEngineとして開発・管理することで、開発効率を大幅に向上させることができるでしょう。