Architecting Multiple Ruby on Rails Applications that Share a Common Code Base NOVA Software Architecture Roundtable Gregory Hodum - ghodum@solutionstreet.com
Business Problem Client wants you to build another RoR application that is similar to the one you just developed…
Business Problem …but different…
Architecture Goals • Share common functionality • Ideally the full MVC stack • Ability to easily customize/extend common functionality • Minimize maintenance • Encourage DRY principle
Solutions? • All-in-one app • Expose common functionality as separate services communicating via API • REST, WS, etc. • Code level organization • Re-usable software component(s) • Ruby gem, Rails Engine • Separate code repositories/projects • Others solutions? Thoughts?
We decided to use Rails Engines
Rails Engines Ruby gem + MVC stack elements http://guides.rubyonrails.org/engines.html
• Rails Engines let applications reuse: • Models / Views / Controllers / Helpers • Assets (JS, CSS, Images) • Routes • Rake tasks • Generators • Initializers • Tests • Migrations and seed data Libraries
blorgh Rails Engine rainbow unicorn Rails App Rails App
Extending Engine Functionality • Overriding/Extending Models and Controllers • Open classing using concerns (Rails ActiveSupport::Concern) • Override Views • Looks in application first, then Engine
Real World Rails Engines • Devise - A flexible authentication solution for Rails • https://github.com/plataformatec/devise • Forem - engine for Rails that aims to be the best little forum system ever • https://github.com/radar/forem • Spree - A complete open source e-commerce solution for Ruby on Rails • https://github.com/spree/spree • RefineryCMS - An open source content management system for Rails • https://github.com/refinery/refinerycms
To generate a new Rails Engine: rails plugin new blorgh --mountable
Then include as a gem in your application’s Gemfile: gem 'blorgh', path: "/path/to/blorgh"
Let’s see the code…
Converting an existing app to use Rails Engines so far… Engine Module/Name-spacing • Be careful with table names, relations, existing app code references to • Engine classes Refactor common classes into Concerns in the Engine • Include filesystem reference to Engine gem during development • Pull specific versions from git during CI/Test/Deployment builds • Angular UI/Assets • Have not tackled this layer yet, another topic for another time • Testing • Standalone tests (RSpec) for the Engine, validates Engine functionality • App test coverage needs to include Engine functionality that has been • overridden/extended
Questions? Additional Thoughts?
References • Code from this presentation: • https://github.com/ghodum/blorgh • https://github.com/ghodum/unicorn • http://guides.rubyonrails.org/engines.html • http://www.slideshare.net/AndyMaleh/rails-engine-patterns • http://hawkins.io/2012/03/defining_plugins_gems_railties_and_engines/ • http://blog.pivotal.io/pivotal-labs/labs/migrating-from-a-single-rails-app-to-a- suite-of-rails-engines#pitfalls • http://www.toptal.com/ruby-on-rails/rails-engines-in-the-wild-real-world- examples-of-rails-engines-in-action
Recommend
More recommend