Railsには任意のRailsアプリケーションを別のRailsアプリケーションにマウントできる仕組みがあります。これを利用して、機能別にRailsアプリケーションを作ってマウントさせることでアプリを育てて行くのはどうかね?という「Maintainable And Scalable Systems With Rails Engines」という記事を見つけたのでご紹介します。
目次
デメリット
Gemfile使えない!
Railsエンジンを使う場合はいわゆるGemを作るときと同じように、.gemspecで使用するGemを定義する必要があります。なので、よくGemfileを使うときにやっているような、Githubから直接落とすような指定などができなくなります。更に、各エンジン間で共通のバージョンのGemを使うように、気をつけておく必要があります。
アセットの共有ができない!
エンジン間でアセットやパーシャルビューの共有を行うことは困難です。とはいえ、パーシャルビューの共有ぐらいはやりたいので、ブログ主は結構ハードな方法で解決しています。
- メインのRailsアプリケーションでパーシャルビューを作成する(例:
shared/_newsletter.html.erb
) - Railsエンジン側では同じ位置に同名で空のパーシャルビューを配置する
これでTemplate Missingは起きなかったようです。とはいえ、嫌な感じはありますよねー。。
マイグレートに気をつけなきゃいけない
それぞれのRailsエンジンに対してマイグレーションが行われるように下準備しておく必要があります。Pivotal Labのleave your migrations in your Rails enginesを参考に、どうぞ。
メリット
再利用可能な部品としてアプリを構成することができる
それぞれのRailsエンジンの扱いはGemと同等なので、再利用可能な部品としてアプリを開発することができます。そもそもこれがやりたかった訳なので、大きなメリットですね。
テストを分割することができる
それぞれのエンジンに対してテストを書けばいいので、機能毎にテストが分割できて綺麗だよねー、という話。(でも、結局結合したテストは書かなきゃいけないんじゃ・・・)
それぞれのエンジンの開発に注力すればいいので、素早く開発できる
それぞれのエンジンは完全にセパレートされているはずなので、開発は素早くできるよねー、という話。
まとめ
各エンジン間を完全に疎結合に設計できれば良いのですが、データを共有する必要のあるケースなどでは、なかなか難しいのではという気がしています。エンジンという物理的な形に分けてしまうよりは、ネームスペースをしっかり区切るといった規約ベースで分ける方が、トラブルが少なそうな気がしました。
僕の経験があるところでは、全く個別のアプリとして立ち上げて、アプリ間はAPIで通信するという形にしたものがあります。これは各アプリでSLAが違ったためなので、ちょっとケースとしては違うかな・・・。
エンジンとしてセパレートして設計する方式はやったことないので、実際試した人がいたら、どんな感じなのか感触を聞いてみたいです。