Rails Engines - Independent Heroes
Tags: rails, beginners
Published: 2020-05-28 18:36:12

Originally published at: [Codegram's blog](https://www.codegram.com/blog/rails-engines-independent-heroes/)

If you have built a Rails *application* in the past, chances are that you used Rails engines already – maybe unknowingly. The well-known [devise](https://github.com/heartcombo/devise) `gem`, for example, is based on Rails engines. But what is it exactly? Well, simply put a Rails `engine` is the **miniature edition** of a Rails *application*. It comes with an `app` folder, including controllers, models, views, routes, migrations... The difference though is, that an `engine` won't work on its own. To show what it's capable of, it needs to become part of something bigger - a part of a main Rails *application*. 

### THE POWER OF INDEPENDENCE

I can hear your question: if we still need a main application and an `engine` is just a small edition of it, why do we need it in the first place?

Well, let me tell you of a van I bought a few years ago. A 1984 Volkswagen LT. Huge, kind of old, lots of adjustments made by more or less experienced former owners with a lack of documentation. Sounds familiar? This could be true for some larger *applications* as well.

![Photo by Tobias Tullius on Unsplash](https://dev-to-uploads.s3.amazonaws.com/i/rbt1mwser155oag7wy0t.jpg)
<small class="text-italic">Like this one, only in red. Photo by [Tobias Tullius](https://unsplash.com/@tobiastu) on [Unsplash](https://unsplash.com/)</small>

When an app starts to grow, when it becomes huge, one can get confused. You are scared to touch file "A" because it is somehow related to file "S" and file "P". Maybe that's not even the case any longer! Maybe you don't need the file "S" any more. Fact is, bigger applications can drive you nuts easily. Wouldn't it be better, if you could **separate** some components? Wouldn't it be better if I could fix, test and improve the wires of my van without the need of the actual van? Or the motor? Sure, it would. And that's exactly why you might want to think about using Rails engines. 

1. You have a nice, clear structure where tasks are separated into different components
2. You can and will test them on their own
3. You can add and remove engines at will from/to your main application

But, same with everything in life, big decisions (*outsourcing parts of a larger application into `engines` is one of these decisions*) come with a good portion of responsibility.

### YOU'RE ALLOWED TO EAT ANYTHING BUT NOT TO KNOW EVERYTHING

With `engines` it's the same as with that German phrase: they can include anything (controllers, models, gems, routes, migrations, ...) but they must **not** know about any behaviour of the main *application*. 

What does that mean? Well, I told you about my van. Like any other car or van, it has a fuel system. This system should work. No matter if it's part of my van, your car or my Dads' bus. It should function totally independent and it should **not** care about the global picture – in this case, the car, van, bus. *If* it cared about it, yes, if it even would rely on the outer shell, what's the idea of having it separated in the first place? Why not creating a fuel system individually made for each car? Sure, that wouldn't make sense at all. And that's why it doesn't make sense for our `engines` either. Use them as **independent** heroes for your main *application*, and don't mix up responsibilities. 

Once you are aware of that, the next thing you want to take care of, is the testing part. Actually, it's kind of the same: you have an independent miniature application that should function on its own, 100% apart from any main *application. S*o, the most obvious solution is testing it separately, right? Right. As the `engine` shouldn't know about anything of the main *application*, stick to tests that are important to that `engine`. That doesn't mean you shouldn't have tests that cover the integration of the `engine` but these tests should sit inside the main application, not inside the `engine`.

![Photo by Ashutosh Dave on Unsplash](https://dev-to-uploads.s3.amazonaws.com/i/8vc1j33l1j3so9ikq70l.jpg)
<small class="text-italic">Photo by [Ashutosh Dave](https://unsplash.com/@ashu) on [Unsplash](https://unsplash.com/)</small>

The first step is always the hardest. But let me give you some resources that will make it easier. For a good technical overview, I'd suggest following the official [Rails engines tutorial](https://guides.rubyonrails.org/engines.html). This shouldn't take too long as you already know what `engines` are. You also can read about "component-based rails _applications_" as they use rails `engines` quite often. Once you feel more confident and aren't afraid of a challenge, head over to **[decidim - The participatory democracy framework](https://github.com/decidim/decidim)**. It's an open-source *application* that is fully based on `engines`. Fully means fully so it might feel a bit overwhelming at the beginning. But as it's open-source, you can see **and** use the whole code. There's also a detailed documentation included, so don't be afraid and give it a try!

And finally, if you want to know why decidim looks the way it looks like and why it's based on `engines`, read the case study on: [codegram - Bringing institutions and people closer together](https://www.codegram.com/our-work/decidim/).

In case you have questions and/or suggestions, I'm happy to hear from you! 

---

*Photo by [Kumiko SHIMIZU](https://unsplash.com/@shimikumi32) on [Unsplash](https://unsplash.com/)*