Could someone please define an Engine in Ruby in Rails? - ruby-on-rails

In computing terms, an engine is something that is continually producing output based on input. But in Ruby, the term seems a little bit loose. The people who've created Refinery CMS have taken to calling gems that extend the functionality of their system, 'engines'.
Basically, what I want to know is, is Spree, the open source ecommerce cms written in ruby, an engine? Would calling it the 'spree engine' be correct?

As defined by Rails, an Engine is a lot like an application within an application. Spree is one of these, and there are others. Each engine has its own app folder with the same sort of structure you'd see in a top-level application.
You can combine one or more engines together into an application, then add your own functionality on top. That's what makes systems like Spree far more flexible than a fixed-puropose Rails app that you have limited control over.
Things that extend Rails are only truly engines if they are self-contained applications. Many gems add functionality that's much more specific than that, so are better termed "plug-ins" or "modules" depending on the phrasing.
It's actually pretty easy to build your own engine and can be useful for separating and re-using code across several different applications.

I think that there is quite good explanation in guide Getting Started with Engines.

Spree is actually comprised of many engines...
The overcooked version: Engines come kitted with (many of) the guts of a typical rails application, with a few bonuses: namespacing out of the box, generators for easily copying migrations, and the ability to mount it in another rails application.

From http://guides.rubyonrails.org/engines.html
1 What are engines?
Engines can be considered miniature applications that provide functionality to their host applications. A Rails application is actually just a "supercharged" engine, with the Rails::Application class inheriting a lot of its behavior from Rails::Engine.
Try to read this guide: http://guides.rubyonrails.org/engines.html and also this cast: http://railscasts.com/episodes/277-mountable-engines

Related

Rails best practice - Engines

I'm currently upgrading an app to rails 4. I planned to install this app for few persons but they have different needs. I decide to use this upgrading version time to put some of my models in engines. The objective is to spend less time tweaking the app for the needs of the situation. The core app will manage the basic resources and the engines will add features (The app is managing membership for small organizations).
I read a lot documentation including the "guides". I tested some engines to see the behaviour of the app. Here are my questions I couldn't answer by my searches:
1 - Naming convention:
How do you name your engines? My first attempt was to name it by their function but when I generated my first model I saw that I can't use the function name for my model.
I was think about something like: Coreappname_functionality
for exemple I want to add activities for my members the engine will be named : member_activities
2 - full vs mountable
I read a lot about this subject, lot of people seem to use mountable engines. I try both of them and I think that the full option is really fast to implement (no routing, no namespace isolation that I have to be aware of). But I also understand the risk for the class collisions. If I'm the only one writing code for this app is it a bad habit to use a full engine(it's just a laziness question). Are there others advantages of mountable engine even if I'm not planning to use them in another app?
3 - "if engine exists?"
Inside the core app i'll put the code that all the engines need. For example inside the side bar I want to display the list of the last activities but only if the activities engine is used. The objective is to put all the necessary code inside the core app but use this code depending on the present of engines or not.
During my test time I used:
if defined? Activity
#activities = Activity.all
end
and render it the views something like this:
<% if defined? Activity %>
<h3><%= #activities.first.title %></h3>
<% end %>
It's working well but I'm not sure that it is a good practice. Is there an alternative?
Do you have any advices before I jump in the engine's world?
I prefer posting my questions before instead of posting my errors after the attempt!
For anybody reading that...
I think there is a misunderstanding about what an isolated engine is. In fact it is a bit confusing. Some may think that's choosing between isolated and not isolated is a bit like a matter of preference. But that's not entirely true.
Isolated engine is just that. An isolated engine. It's not suitable for a "module" of your application. It's more like a "subapplication" of you application. The difference is critical. Modules of your application probably will share models, api or some business logic. Still, encapsulation of responsibilities is important, but there will be some connections. For example probably almost all of your modules will be using something like EventDispatcher module. While isolated engine is a whole application on it's own. Although it could use models from the host application it can't use models from different isolated engine (at least without hacks, a lot of pain in 'certain situations' and that's generally a bad idea causing bad design).
So if you try to implement your app modules using isolated engines your probably end up storing all your models in main/host application to be reusable between your - in fact - subapplications. Probably the same with views. And maybe with assets too. And if some business logic have to be shared it probably would end up in main application too. So that's basically defeats the whole purpose. That's why you should use not isolated engines for your modules. While isolated engines are good for a - totally encapsulated - subapplication. For example if you want to have an e-commerce shop alongside with your main application (spree gem does exactly that).
A more enterprise example would be an ERP system. It could have subapplications like: CRM, Resource Management, etc (isolated engines). And those subapplications could have their own modules (not isolated engines).
Just for the completeness of my answer. As a isolated engine i mean that generated using rails plugin new engine_name --mountable, while a not isolated would be generated using rails plugin new engine_name --full.
Disclaimer:
Maybe there are some cases when you would want to go different way (probably when implementing some kind of magic gem doing some magic things), but that's up to you to figure it out. By this answer I just mean it should be applicable in most applications.

What are practical uses of mountable engines?

Just finished watching "Railscast 277" on mountable engines in Rails, what are practical uses of mountable engines?
One of the best examples would be Devise (for authentication) which is an engine (plugin) but its mounted as a shared-engine; you also get namespaced engines and this helps to retain a sense of context.
Another example would be the Active Admin add-on, error notification plugins...and a whole lot more. In terms of 'mounting' from a purely routing point of view, you can see how — with a namespaced engine you can serve a completely isolated rails app from a route from within your app itself.
You should consider reading this as well.
Two major uses:
Reusability. Gems that expose a lot of application functionality are often distributed as engines.
Modularity. Particularly for large applications, there are often parts of the application that don't seem like they want to be mixed in with the main application, yet are too closely related to be extracted to entirely separate applications. Engines can work well for this.
Spree takes this to extremes: the core Spree framework is the main Rails application, and to customize it, you write engines. This means you're never modifying the Spree core directly.

Rails Ruby Gems vs Pure Development When Generating A Rich Blog

Some ruby gems like jekyll, toto and webby offer out of the box blog-type integration into your ruby app. Another way of developing a rich web blog-type application is to build and model the application yourself using pure ruby and rails practices. (e.g creating an Article and User model). The first offers out of the box features the 2nd option offers more customization and control.
In people's experience on Stack Overflow, which would be the best route and what would people consider when making the decision to use a gem out of the box versus going alone?
All of the gems you mentioned take static, markdown/textile/etc files and turn them into HTML websites. They take different approaches to it, with jekyll spitting out the finished website for hosting, toto doing the converting and routing on request, and webby doing the same as jekyll mostly.
If you're using Rails, it's important to note that none of these will integrate into your application well. They're built to more-or-less operate on their own.
Generally speaking, if a gem has the functionality you need, use it. They are not equivalent to plugins you find for Wordpress and Drupal where they are typically low-quality, buggy, poorly documented, etc. More often than not, gems simply add a couple modules that you can integrate into your application how you like.
On the other hand, a basic blog is pretty quick and simple in Rails, especially considering you've got a handy walkthrough guide straight from the Rails documentation on how to do it.
If you're new to Rails and want tight integration with your app, it's probably best to bake your own blog features.
This will take some time to do, but its worth it to learn how things really work.
If you're more seasoned, just look at the gem's API and documentation and decide if it does what you want it to do and if you're comfortable with how to integrate it. If so, it'll save you time.
One other consideration: who will be using the blog? Is it for internal use, and programmers will be the ones updating it? If that's the case, then you can make it very easy by not worrying about a lot of aesthetic polish in the back-end. Conversely, if you're making an app that includes a blogging component for the general public you might want it to feel more polished. In this case a gem might save you a lot of time.
It depends on your application.

Is it possible to create sub-applications in Ruby on Rails 3 or something like slices from Merb?

Does Rails 3 have anything akin to slices in Merb, or areas in Django where there is a layer of organization above the controller? I heard at some point that they may allow hosting one rails app within another but I can't find any information on that in the pre-release material. Any hints on how to do something like this?
You're right there doesn't seem to be a lot of official documentation on it yet. But yes, you can have application slices -- they're called engines in Rails. Actually they've been available in Rails since 2.3. Currently, you basically make a plugin that has a complete application structure and set up your routes in there to "mount" your app against a specific URL. In Rails 3, engines are basically first-class objects in the Rails stack. I believe they can still be plugins but you will also be able keep it away from your application in a separate gem and require it in your application much more easily. You should be able to find stuff pretty easily on teh Google, but here's an oft-linked but informative reference: https://gist.github.com/af7e572c2dc973add221

How do I have plugin architecture in Ruby on Rails?

I have to built a social networking site on Ruby on Rails. The features in the site may change from time to time; so we will need to add/remove features with ease. Moreover, we may be building another social networking site. Due to these reasons, we are thinking to build a basic framework for social networking sites in RoR with the feature to install or uninstall extensions to the framework.
I worked previously in Joomla! CMS and its architecture for adding/removing extensions is kind of what I am looking at. In a Joomla! installation there is usually an admin side from which you can add/remove/customize extensions.
I am new to RoR and finding it little difficult to decide how to do this. Any help will be appreciated.
UPDATE 2015: this was answered in 2009 a lot has changed
Plug-ins have been superseded by Gems and Engines
For all the information you need on Engines:
http://guides.rubyonrails.org/engines.html
Engines are a fantastic way of building encapsulated and reusable code for your rails apps.
Original Answer for Reference
On the development side Rails Engines and/or plugins is probably what you are looking for.
Rails Engines are small subsets of an
application that can be dropped into
any of your Rails applications and
handle common parts of the application
from scratch.
Say for example your social networking application has a wiki, blog, chatroom etc. You would more than likely want to create a wiki engine, blog engine and chatroom engine.
Engines allows you to re-use such functionality within different applications so you do not have to repeat yourself.
Take a look at: http://rails-engines.org/
Some support for ‘engine’ plugins has
been merged into the Rails core
codebase in Rails 2.3.
I would also recommend taking a look at some public projects say on github and see how people have used engines.
Take a look at some engines:
Wiki-Engine
Skinny-Blog-Engine
Other useful links for reading
Tips for writing Engines
Rails Engines, Railscast by Ryan Bates
The Russian Doll Pattern (PDF)
In functionality terms you could still have an admin area that could activate certain features ie. your blog or wiki by allowing users access to such areas with a permissions/roles system.
ACL9
role_requirement
restful-authentication
If you want to build a CMS which supports some kind of extensions like in Wordpress or Joomla then you will have to either build it and provide guidlines or at least look into how you would upload/install Engines/Plugins from a user perspective.
Not sure on the security implications of this
Redmine has put this kind of functionality into their awesome application. You may want to dig around the source code for tips and clues
Finally Adva_CMS has basically adopted this approach and have created a number of Engines for their CMS application
HTH
Engines are still a pretty solid way to go, the new location to get info on those is located here: http://guides.rubyonrails.org/engines.html
But what you need is really more application specific. A lot of applications develop these things organically over time. They start out by hand crafting a few of these and then they re-factor them periodically until they find patterns that align with software design patterns and then they develop a plugin framework.
Are you going to expose your interface to end users? To third party developers? What parts of the application are controlled by these plugins? Is it just the presentation tier? Does it affect the data model? Consider the fact that when you publish any kind of external interface, you're developing contracts that you need to honor.
You might check out these design patterns: http://en.wikipedia.org/wiki/Software_design_pattern. They will help you figure out how to manage your development process. If you're just working on plugins for internal use, then what's the real purpose of them? What makes them different than modules?

Resources