Rails 4 Engines
tech.taskrabbit.com
tech.taskrabbit.com
- Rails' use of folder for autoloading can encapsulate part of your application like engine does. (app/models/admin/post.rb vs app/models/post.rb)
- Different dependencies will turn on you in the long run. You're shoveling the problem ahead.
- Routing between different engine is cumbersome because of lack of autodiscovery (You can't know easily at run time which engine is mounted)
For "knowing what's enabled" we use the BootInquirer I mention, though we've never had to to know at runtime. The interesting stuff comes up when we have to sync the routing to our load balancer, which we haven't fully automated, though it seems possible.
- yep. It is unfortunate. Always stick to the default folder structure (subfolders for modules) to prevent any weird interactions among engines and between engines and the main app.
- Prevent this by not allowing this. You would not have different dependencies within one Rails app and you can't have it with a component-based architecture.
- Routing between engines should be much less frequent than routing within. A perfect case for preventing unnecessary dependencies by creating "engine routing intrefaces"
Bonus: directory layouts, since they're conceptually connected:
http://guides.rubyonrails.org/getting_started.html#creating-...
http://www.deploydjango.com/django_project_structure/index.h...
----
The other important point on large scale Rails architecture is that common functionality can/should be extracted to Rails plugins, which can then be turned into Ruby gems.
http://guides.rubyonrails.org/plugins.html
Great Rails project: https://github.com/diaspora/diaspora which uses MVCP (Presenter)
The other bit it to make use of concerns in Rails 4 for extra DRY controllers and models:
https://stackoverflow.com/questions/14541823/how-to-use-conc...
The ease of running integration/acceptance tests in this kind of setup is a huge help, especially if the app already has tests covering the behavior you're trying to maintain while splitting things out.
It's hella warty in places but overall it provides a lot better "separation of responsibilities", and I too recommend this approach.
I agree with you if it's intended to be packaged as a gem, but if I'm only using it as a namespace separator, then it's pointless to fret about where it all goes - they were never meant to be used separately in the first place.
Kind of scary how few people know how to set up nginx anymore.
You should also be able to setup a heroku nginx app that proxies to other heroku apps.
http://www.youtube.com/playlist?list=PLjQo0sojbbxUav7I746f0l... /shameless self promotion
I recommend using Ubuntu server and using the BrightBox PPA to install 2.1. Updates are an apt-get away, and adding PPAs is far easier to do with configuration management than managing rbenv or rvm.
I use rbenv in development and it's a godsend. I keep it the hell away from production, though.
Getting OS support for brand new software packages is tough. It's not just the package itself that needs support but all the things that depend on it.
If you have to use red hat, then you should probably either stick with 2.0 or just use rbenv until a proper package is released.
Switch to at least 2x-sized dynos and use nginx-buildpack (https://github.com/ryandotsmith/nginx-buildpack) with multi-buildpack (https://github.com/ddollar/heroku-buildpack-multi).
You'll probably need to modify/fork the ruby buildpack to do asset compiles twice (if necessary) and check-in both apps into the same repo. And of course modify the nginx configuration.
I'm not sure that rails 4 sessions can be shared with rails 2 sessions.
One very large advantage of multiple apps is they can run on different hardware with separate databases. For example my attachment service runs on a server with libreoffice and x11 installed.
So in theory using the BootInquirer I should be able to boot multiple variations of the application.
For instance I could boot all engines when in development mode but deploy them as separate services with separate databases in production.
Thanks taskrabbit I now know how I am going to spend the rest of my week.
It's very tempting to do model sharing because it just makes things so easy but I can definitely see having to rewrite models when the time comes to scale out the parts of the app that is getting more hits. With your approach I wouldn't have to worry about that because it's modular from the start.
Would love to give this approach a try! Thx for the article.
Rails Engine seems like a full ruby realization of this previous dream of mine.
After having gone down the path of separate API controllers, we learned that the APIs had become a second class citizen and had different code paths than the web based resources.
We unified everything; the same endpoint that the user goes through for web signup is the same endpoint that the API will request for a create.
We're just using respond_to's to respond to the various types of clients that make requests.
Utilizing Rails, Jbuilder, and VersioCake, we have a unified, versioned API that can support earlier client versions (thanks to VersionCake).
That kind of thing.