Mounting applications within applications is a powerful technique, that allows developers to build highly scalable applications that are both cost effective and easy to maintain. Rails Engines give developers the power to transform a rails apps into ruby gems. Many popular ruby gems such as Device and Spree leverage rails engines to provide default custom views like login forms. Having a suite of rails engines has a ton of advantages and I would recommend refactoring large monolith apps into smaller engines.
As an example, i’m going to set up a blog that is made up of two component applications a
blog_core (the core application). I’m not going to do anything fancy, i’m just going to set up each component as separate rails apps and write a little extra code to make them “mountable”.
Let’s start by, first, setting up the API.
We also setup a gemspec; this allows us export our rails app as a ruby gem.
Next, we’re going to setup the engine itself for our blog API.
Next, we’re going to add one more file
That’s it, our blog API is now a ruby gem!
Now that we have our blog API gem we can include in our core application.
First, we need to setup our core app.
In our gem file we’re going to include the
blog_api gem that we just created, using a relative path.
Next, we need to run the
blog_api migrations with
And that’s it! We have successfully mounted our
So this was just a boilerplate example of using rails engines (just to get started). There are many ways of making your rails engine more robust, such as mounting an engine on a specific route or autosyncing database migrations. I’m not going to go into too much depth in optimizing a rails engine in this post , there are plenty of resources online to help you out, if you’re interested in doing that, but I will briefly cover autosyncing database migrations since it’s fairly easy to accomplish.
Interestingly, Rails Engines inherent from Railties. Railties allow developers to hook into and extend the Rails initialization process. So we can write initializers in our
blog_api engine and Rails will execute the initializers when the gem is required.
Let’s set up an initialization process to append the
blog_api migrations to the migrations found in
Now we can simply run
rake db:migrate and
blog_core will know to include the