SlideShare a Scribd company logo
1 of 63
Problem
 Difficulty reusing functionality cutting across:
   Models
   Views
   Controllers
   Assets (JS, CSS, Images)
 Duplication across all web application layers.
Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
Solution
 Break common behavior into Rails Engines

 Customize models/controllers/helpers in each
 project where needed by reopening classes

 Customize Rails views in each project as needed
 by overriding templates

 Link to Rails Engines in Gemfile via Git repo
Example
                     Common
                     Domain
                       Rails Engine



          Search Map
             Rails Engine


  High School         Public           Athlete
   Recruiting        Profiles         Recruiting
      Rails App         Rails App        Rails App
Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
What is a Rails Engine?

       Ruby Gem
            +
  MVC stack elements
What is a Rails Engine?
 Rails Engines let applications reuse:
   Models / Views / Controllers / Helpers
   Assets (JS, CSS, Images)
   Routes
   Rake tasks
   Generators
What is a Rails Engine?
 Rails Engines let applications reuse:
   Initializers
   RSpec / Cucumber
   Rack application with middleware stack
   Migrations and seed data
   Libraries
Engine Definition
 An engine structure is similar to a Rails app
 having app, config, lib, spec, features, etc…
 lib/engine_name.rb (read online instructions)
 lib/engine_name/engine.rb (read online
 instructions)
 To reuse engine, use “jeweler” gem to generate
 gemspec (read online instructions)
lib/engine_name.rb
lib/engine_name/engine.rb
Engine Consumption
    Reference engine via Gemfile as a Ruby gem or
    Git repo hosted gemified project:




Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
Load Order
 Typically Rails app files load first before Engine
 files.

 Strongly recommended to reverse so that
 engine’s code is customizable in app
Load Order
 Reversing load order can happen in one of two
 ways:
  Patching “active_support/dependencies.rb” in
  Rails 3.1- (see next slide)
  Adjusting railties_order in Rails 3.2+
Ruby Code Customization
 Model/Helper/Controller behavior can be
 customized be redefining .rb files in Rails App
 Customizations get mixed in with files in Engine
 This allows:
   Adding new methods/behavior
   Replacing existing methods
   Extending existing methods (alias_method_chain)
Ruby Code
Customization Example
Ruby Code
Customization Example
View and Asset
Customization
 Engine View and Asset presentation can be
 customized by redefining files in Rails App
 Customizations completely override files in Engine
 Examples of customizable View and Asset files:
   ERB/Haml
   JS
   CSS
   Images
View
Customization Example
View
Customization Example
Recommended Engine
Code Management
• Each Engine lives in own Repo independent of
  Rails App

• Each Engine has its own Gem dependencies
  (Gemfile)

• Engines preferably share the same Ruby version
  as Rails App
Typical Development
Process
1. Make changes in engine, rake, and commit
   obtaining a new GIT ref
2. Update Gemfile in app with new git ref, run
   “bundle install” (getting ride of symlink)
3. Rake and commit changes in app.
4. If more changes in engine are needed go back
   to step 1
Improved Productivity via
Symlinking
 Multiple engine dependencies can hamper
 productivity when frequently going back and
 forth between engines and app
 Engine gems installed via bundler can be
 symlinked to allow continuous development until
 done with both app and
 engine:http://andymaleh.blogspot.com/2011/09/
 more-productive-rails-engine.html
Improved Development
Process
1. Open Rails app and symlink all engines “rake
   engine:symlink[engine_name]”
2. Work in app and engine until done WITHOUT running
   “bundle install”
3. Rake and commit changes in engine obtaining a new git
   ref
4. Update Gemfile in app with git ref, run “bundle install”
   (getting ride of symlink)
5. Rake and commit changes in app
Engines Reuse Engines
 Rails engines can reuse other Rails engines
                           Common
                           Domain
                            Rails Engine



               Search Map
                   Rails Engine


        High School         Public          Athlete
         Recruiting        Profiles        Recruiting
            Rails App         Rails App       Rails App
Engines Reuse Engines
 When multiple levels of depth are involved,
 commit repos and update Gemfile from the
 bottom up

 Example: Engine 2 => Engine 1 => App
 1. Commit in Engine 2
 2. Update Gemfile in Engine 1 and commit
 3. Update Gemfile in App and commit
Engine Configuration
 Engines can be configured to customize rack
 middleware, load paths, generators, and Rails
 component paths. More details at:
 http://edgeapi.rubyonrails.org/classes/Rails/Engi
 ne.html
Isolated Engines
 To avoid Ruby namespace clash with
 Models/Helpers/Controllers, you can define an
 isolated namespaced engine.

 For more details, go to
 http://edgeapi.rubyonrails.org/classes/Rails/Engi
 ne.html
Rails Engine Patterns
 Goals:
  Keep engine code agnostic of app customizations
  Prevent bi-directional coupling to simplify
  reasoning about code
  Avoid app dependent conditionals to improve code
  maintainability
Pattern - Common Domain
 Problem: Multiple Rails Apps need to share a basic
 domain model including default CRUD and
 presentation behavior

 Example: need to reuse address model and form
 entry behavior
Pattern - Common Domain
 Solution:
  In engine, include basic domain models (base
  behavior, common associations) with their views,
  CRUD controllers, and routes.
  In each app, define domain model specialized
  behavior, extra associations, and custom views
  Make sure routes are declared with
  Rails.application.routes.draw (not Rails App name)
Pattern - Common Domain
 Example: address.rb, addresses_controller.rb,
 address route, and _address.html.erb
Pattern - Expose Helper
 Problem: need to customize presentation logic for a
 view in one app only, but keep the same logic in
 others
 Example:
   One App needs to hide address1 and county for non-
   government users.
   Other Apps wants to keep the fields displayed.
   You might start by overriding view, but then realize it is
   duplicating many elements just to hide a couple fields.
Pattern - Expose Helper
 Solution:
  In Engine, extract helper logic that needs
  customization into its own helper.
  In App, redefine that new helper with
  customizations.
Pattern - Expose Helper
(view in Engine)
Pattern - Expose Helper
(trying to customize view in App)
Pattern - Expose Helper
 Remove custom view from App

 Use requires_extended_address? helper in Engine
 wherever the App used government_user?

 In Engine, define requires_extended_address? to
 return true

 In App, define requires_extended_address? to return
 government_user?
Pattern - Expose Helper
(view + helper in Engine)
Pattern - Expose Partial
 Problem: need to have different customizations
 in one part of the view in multiple apps

 Example: Address form
  One App needs an extra neighborhood field
  Another App needs an extra region field
Pattern - Expose Partial
 Example App 1:
Pattern - Expose Partial
 Example App 2:
Pattern - Expose Partial
 Solution:
  In Engine, extract view part that needs
  customization as a partial.
  In App, redefine that partial with customizations.
Pattern - Expose Partial
 Example:
  Define _address_extra_fields partial with empty
  content in Engine
  Redefine _address_extra_fields in Apps needing
  extra fields
Pattern - Extension Point
 Problem: multiple Apps need to contribute data
 to a View in different places

 Example: multiple Apps need to add custom
 Rows in different spots of a List that comes from
 an Engine
Pattern - Extension Point
 Engine defines only 3 elements in a list (About
 Me, News and Noteworthy)

               1

               2

               3
Pattern - Extension Point
 Solution:
  In Engine, add Helper logic that looks up partials in
  a specific ext directory, and based on file name
  (e.g. row_7.html.erb) insert into the right location
  in the View.
  In App, define these partials with the right file
  names and locations.
Pattern - Extension Point
 App 1 adds “nav_bar_list_ext/_row_1.html.erb”


              1

              2

              3


              4
Pattern - Extension Point
 App 2 adds “nav_bar_list_ext/_row_4.html.erb”


              1

              2

              3


              4
Pattern - Configurable
Features
 Problem: different apps need different features
 from an engine in different combinations
Pattern - Configurable
Features
 Solution:
  In Engine, add logic that looks up configuration
  options
  In App, configure Engine by overriding
  configuration options
Pattern - Configurable
Features
 Example:
  Engine defines engine_config.yml
  enable_address_extensions: true
  enable_address_headers: true
  App overrides some options in engine_config.yml
  Engine uses config options to customize behavior
  using conditionals
Rails Engine Costs
 Overhead in establishing a new Rails Engine
 gem project

 Continuous switching between projects and
 engines to get work done

 Upgrade of ref numbers in Gemfile on every
 commit (minimized with symlinking)
Rails Engine Benefits
 Code reuse across all application layers

 Better maintainability due to:
   Independent project codebases
   Cleanly defined boundaries between projects and
   reusable components (engines)
 Project tests get smaller and run faster
Engines vs Services
 Engines are better when:
  Reusing small MVC features, especially domain
  independent (e.g. Search Map)
  Preferring to avoiding network and infrastructure
  overhead over establishing a service
  Wanting to quickly extract and reuse a feature
Engines vs Services
 Web Services are better when:
  Reusing larger MVC features that depend on
  domain data
  Need to consume feature in another programming
  language or outside the organization boundaries
  Need to scale up feature performance
  independently of the application (e.g. separate DB)
Engines vs Services
 To keep an easier to maintain Agile code base,
 start simple and then move incrementally
 towards a more complex architecture:
  Extract an MVC feature as an engine first
  Convert engine into a service when the need
  arises
Questions & Answers



      ???
Review
 Basics of Rails Engines

 Rails Engine Patterns

 Improved Productivity Tips

 Summary of Benefits and Trade-Offs
More Info
 http://edgeapi.rubyonrails.org/classes/Rails/Engi
 ne.html

 http://andymaleh.blogspot.com/2011/09/more-
 productive-rails-engine.html

 http://stackoverflow.com/questions/2964050/rail
 s-engines-extending-
 functionality/2990539#2990539
Contact
 Andy Maleh / Software Engineer / Groupon
  Email: amaleh {at} groupon {dot} com
  Code Painter Blog: http://andymaleh.blogspot.com
  Twitter: @AndyMaleh

More Related Content

What's hot

Is 12 Factor App Right About Logging
Is 12 Factor App Right About LoggingIs 12 Factor App Right About Logging
Is 12 Factor App Right About LoggingPhil Wilkins
 
Introduction to Android and Android Studio
Introduction to Android and Android StudioIntroduction to Android and Android Studio
Introduction to Android and Android StudioSuyash Srijan
 
Introduction to Apache solr
Introduction to Apache solrIntroduction to Apache solr
Introduction to Apache solrKnoldus Inc.
 
Introduction to React JS
Introduction to React JSIntroduction to React JS
Introduction to React JSArno Lordkronos
 
androidstudio.pptx
androidstudio.pptxandroidstudio.pptx
androidstudio.pptxSundaresanB5
 
UI controls in Android
UI controls in Android UI controls in Android
UI controls in Android DivyaKS12
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming LanguageGiuseppe Arici
 
NodeJS - Server Side JS
NodeJS - Server Side JS NodeJS - Server Side JS
NodeJS - Server Side JS Ganesh Kondal
 
Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...
Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...
Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...Cihan Özhan
 
Android Application Development Using Java
Android Application Development Using JavaAndroid Application Development Using Java
Android Application Development Using Javaamaankhan
 
Single page application
Single page applicationSingle page application
Single page applicationArthur Fung
 
React.js Web Programlama
React.js Web ProgramlamaReact.js Web Programlama
React.js Web ProgramlamaCihan Özhan
 

What's hot (20)

Is 12 Factor App Right About Logging
Is 12 Factor App Right About LoggingIs 12 Factor App Right About Logging
Is 12 Factor App Right About Logging
 
API
APIAPI
API
 
Html5 Basic Structure
Html5 Basic StructureHtml5 Basic Structure
Html5 Basic Structure
 
Learn react-js
Learn react-jsLearn react-js
Learn react-js
 
Sikuli
SikuliSikuli
Sikuli
 
Introduction to Android and Android Studio
Introduction to Android and Android StudioIntroduction to Android and Android Studio
Introduction to Android and Android Studio
 
Introduction to Apache solr
Introduction to Apache solrIntroduction to Apache solr
Introduction to Apache solr
 
Introduction to React JS
Introduction to React JSIntroduction to React JS
Introduction to React JS
 
Django
DjangoDjango
Django
 
androidstudio.pptx
androidstudio.pptxandroidstudio.pptx
androidstudio.pptx
 
UI controls in Android
UI controls in Android UI controls in Android
UI controls in Android
 
Application development framework
Application development frameworkApplication development framework
Application development framework
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
NodeJS - Server Side JS
NodeJS - Server Side JS NodeJS - Server Side JS
NodeJS - Server Side JS
 
Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...
Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...
Yapay Zeka Güvenliği : Machine Learning & Deep Learning & Computer Vision Sec...
 
Introduction to Microservices
Introduction to MicroservicesIntroduction to Microservices
Introduction to Microservices
 
Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
 
Android Application Development Using Java
Android Application Development Using JavaAndroid Application Development Using Java
Android Application Development Using Java
 
Single page application
Single page applicationSingle page application
Single page application
 
React.js Web Programlama
React.js Web ProgramlamaReact.js Web Programlama
React.js Web Programlama
 

Viewers also liked

Rails Engines - A presentation for the 22nd Athens Ruby Meetup
Rails Engines - A presentation for the 22nd Athens Ruby MeetupRails Engines - A presentation for the 22nd Athens Ruby Meetup
Rails Engines - A presentation for the 22nd Athens Ruby MeetupSkroutz S.A.
 
How to build a data warehouse - code.talks 2014
How to build a data warehouse - code.talks 2014How to build a data warehouse - code.talks 2014
How to build a data warehouse - code.talks 2014Martin Loetzsch
 
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...Andy Maleh
 
Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012
Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012
Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012Andy Maleh
 
The Rails Engine That Could - In Motion
The Rails Engine That Could - In MotionThe Rails Engine That Could - In Motion
The Rails Engine That Could - In MotionAndy Maleh
 
RailsConf 2014 Recap at Montreal.rb by Andy Maleh
RailsConf 2014 Recap at Montreal.rb by Andy MalehRailsConf 2014 Recap at Montreal.rb by Andy Maleh
RailsConf 2014 Recap at Montreal.rb by Andy MalehAndy Maleh
 
How I Learned To Apply Design Patterns
How I Learned To Apply Design PatternsHow I Learned To Apply Design Patterns
How I Learned To Apply Design PatternsAndy Maleh
 
Distributed Ruby and Rails
Distributed Ruby and RailsDistributed Ruby and Rails
Distributed Ruby and RailsWen-Tien Chang
 
Software Craftsmanship VS Software Engineering
Software Craftsmanship VS Software EngineeringSoftware Craftsmanship VS Software Engineering
Software Craftsmanship VS Software EngineeringAndy Maleh
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails PresentationJoost Hietbrink
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentationadamcookeuk
 

Viewers also liked (14)

Git Branching Model
Git Branching ModelGit Branching Model
Git Branching Model
 
Rails Engines - A presentation for the 22nd Athens Ruby Meetup
Rails Engines - A presentation for the 22nd Athens Ruby MeetupRails Engines - A presentation for the 22nd Athens Ruby Meetup
Rails Engines - A presentation for the 22nd Athens Ruby Meetup
 
How to build a data warehouse - code.talks 2014
How to build a data warehouse - code.talks 2014How to build a data warehouse - code.talks 2014
How to build a data warehouse - code.talks 2014
 
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
 
Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012
Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012
Revised Rails Engine Patterns for Montreal.rb meetup Oct 16, 2012
 
The Rails Engine That Could - In Motion
The Rails Engine That Could - In MotionThe Rails Engine That Could - In Motion
The Rails Engine That Could - In Motion
 
RailsConf 2014 Recap at Montreal.rb by Andy Maleh
RailsConf 2014 Recap at Montreal.rb by Andy MalehRailsConf 2014 Recap at Montreal.rb by Andy Maleh
RailsConf 2014 Recap at Montreal.rb by Andy Maleh
 
How I Learned To Apply Design Patterns
How I Learned To Apply Design PatternsHow I Learned To Apply Design Patterns
How I Learned To Apply Design Patterns
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Distributed Ruby and Rails
Distributed Ruby and RailsDistributed Ruby and Rails
Distributed Ruby and Rails
 
Software Craftsmanship VS Software Engineering
Software Craftsmanship VS Software EngineeringSoftware Craftsmanship VS Software Engineering
Software Craftsmanship VS Software Engineering
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Build Features, Not Apps
Build Features, Not AppsBuild Features, Not Apps
Build Features, Not Apps
 

Similar to Rails Engine Patterns

The Rails Engine That Could
The Rails Engine That CouldThe Rails Engine That Could
The Rails Engine That CouldAndy Maleh
 
Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013
Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013
Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013Mack Hardy
 
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - AppenginePython Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - AppenginePython Ireland
 
Migration from Rails2 to Rails3
Migration from Rails2 to Rails3Migration from Rails2 to Rails3
Migration from Rails2 to Rails3Umair Amjad
 
Rails
RailsRails
RailsSHC
 
Backbonification for dummies - Arrrrug 10/1/2012
Backbonification for dummies - Arrrrug 10/1/2012Backbonification for dummies - Arrrrug 10/1/2012
Backbonification for dummies - Arrrrug 10/1/2012Dimitri de Putte
 
How to set up and test a Rails 3 Engine
How to set up and test a Rails 3 EngineHow to set up and test a Rails 3 Engine
How to set up and test a Rails 3 Enginenicholasf
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2Rory Gianni
 
Pluggable patterns
Pluggable patternsPluggable patterns
Pluggable patternsCorey Oordt
 
Ember js java script framework
Ember js   java script frameworkEmber js   java script framework
Ember js java script frameworksara stanford
 
iPhone Web Development and Ruby On Rails
iPhone Web Development and Ruby On RailsiPhone Web Development and Ruby On Rails
iPhone Web Development and Ruby On RailsJose de Leon
 
Ruby Rails Web Development
Ruby Rails Web DevelopmentRuby Rails Web Development
Ruby Rails Web DevelopmentSonia Simi
 

Similar to Rails Engine Patterns (20)

Rails review
Rails reviewRails review
Rails review
 
The Rails Engine That Could
The Rails Engine That CouldThe Rails Engine That Could
The Rails Engine That Could
 
Rails engines
Rails enginesRails engines
Rails engines
 
Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013
Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013
Strategies and Tips for Building Enterprise Drupal Applications - PNWDS 2013
 
Rails interview questions
Rails interview questionsRails interview questions
Rails interview questions
 
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - AppenginePython Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
 
Angular2 and You
Angular2 and YouAngular2 and You
Angular2 and You
 
Migration from Rails2 to Rails3
Migration from Rails2 to Rails3Migration from Rails2 to Rails3
Migration from Rails2 to Rails3
 
Rails engine
Rails engineRails engine
Rails engine
 
Rails
RailsRails
Rails
 
Rail3 intro 29th_sep_surendran
Rail3 intro 29th_sep_surendranRail3 intro 29th_sep_surendran
Rail3 intro 29th_sep_surendran
 
Backbonification for dummies - Arrrrug 10/1/2012
Backbonification for dummies - Arrrrug 10/1/2012Backbonification for dummies - Arrrrug 10/1/2012
Backbonification for dummies - Arrrrug 10/1/2012
 
How to set up and test a Rails 3 Engine
How to set up and test a Rails 3 EngineHow to set up and test a Rails 3 Engine
How to set up and test a Rails 3 Engine
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2
 
Pluggable patterns
Pluggable patternsPluggable patterns
Pluggable patterns
 
Ruby on rails RAD
Ruby on rails RADRuby on rails RAD
Ruby on rails RAD
 
Ember js java script framework
Ember js   java script frameworkEmber js   java script framework
Ember js java script framework
 
iPhone Web Development and Ruby On Rails
iPhone Web Development and Ruby On RailsiPhone Web Development and Ruby On Rails
iPhone Web Development and Ruby On Rails
 
Aspose pdf
Aspose pdfAspose pdf
Aspose pdf
 
Ruby Rails Web Development
Ruby Rails Web DevelopmentRuby Rails Web Development
Ruby Rails Web Development
 

More from Andy Maleh

Fukuoka Ruby Award 2023 - Opal
Fukuoka Ruby Award 2023 - OpalFukuoka Ruby Award 2023 - Opal
Fukuoka Ruby Award 2023 - OpalAndy Maleh
 
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby MeetupBecoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby MeetupAndy Maleh
 
Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ...
 Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ... Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ...
Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ...Andy Maleh
 
How I Built My Code Editor in Ruby
How I Built My Code Editor in RubyHow I Built My Code Editor in Ruby
How I Built My Code Editor in RubyAndy Maleh
 
Ultra Light and Maintainable Rails Wizards at RailsConf 2014
Ultra Light and Maintainable Rails Wizards at RailsConf 2014Ultra Light and Maintainable Rails Wizards at RailsConf 2014
Ultra Light and Maintainable Rails Wizards at RailsConf 2014Andy Maleh
 
Ultra Light and Maintainable Wizards in Rails at Montreal.rb
Ultra Light and Maintainable Wizards in Rails at Montreal.rbUltra Light and Maintainable Wizards in Rails at Montreal.rb
Ultra Light and Maintainable Wizards in Rails at Montreal.rbAndy Maleh
 
Software Craftsmanship vs Software Engineering (Lightning Talk)
Software Craftsmanship vs Software Engineering (Lightning Talk)Software Craftsmanship vs Software Engineering (Lightning Talk)
Software Craftsmanship vs Software Engineering (Lightning Talk)Andy Maleh
 
Software Design Trilogy Part II - Design Patterns for Rubyists
Software Design Trilogy Part II - Design Patterns for RubyistsSoftware Design Trilogy Part II - Design Patterns for Rubyists
Software Design Trilogy Part II - Design Patterns for RubyistsAndy Maleh
 
Software Design Trilogy Part I - Responsibility Driven Design for Rubyists
Software Design Trilogy Part I - Responsibility Driven Design for RubyistsSoftware Design Trilogy Part I - Responsibility Driven Design for Rubyists
Software Design Trilogy Part I - Responsibility Driven Design for RubyistsAndy Maleh
 
Simplifying Desktop Development With Glimmer
Simplifying Desktop Development With GlimmerSimplifying Desktop Development With Glimmer
Simplifying Desktop Development With GlimmerAndy Maleh
 

More from Andy Maleh (10)

Fukuoka Ruby Award 2023 - Opal
Fukuoka Ruby Award 2023 - OpalFukuoka Ruby Award 2023 - Opal
Fukuoka Ruby Award 2023 - Opal
 
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby MeetupBecoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
 
Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ...
 Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ... Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ...
Montreal.rb 2022-10-05 - Glimmer DSL for SWT - Ruby Desktop Development GUI ...
 
How I Built My Code Editor in Ruby
How I Built My Code Editor in RubyHow I Built My Code Editor in Ruby
How I Built My Code Editor in Ruby
 
Ultra Light and Maintainable Rails Wizards at RailsConf 2014
Ultra Light and Maintainable Rails Wizards at RailsConf 2014Ultra Light and Maintainable Rails Wizards at RailsConf 2014
Ultra Light and Maintainable Rails Wizards at RailsConf 2014
 
Ultra Light and Maintainable Wizards in Rails at Montreal.rb
Ultra Light and Maintainable Wizards in Rails at Montreal.rbUltra Light and Maintainable Wizards in Rails at Montreal.rb
Ultra Light and Maintainable Wizards in Rails at Montreal.rb
 
Software Craftsmanship vs Software Engineering (Lightning Talk)
Software Craftsmanship vs Software Engineering (Lightning Talk)Software Craftsmanship vs Software Engineering (Lightning Talk)
Software Craftsmanship vs Software Engineering (Lightning Talk)
 
Software Design Trilogy Part II - Design Patterns for Rubyists
Software Design Trilogy Part II - Design Patterns for RubyistsSoftware Design Trilogy Part II - Design Patterns for Rubyists
Software Design Trilogy Part II - Design Patterns for Rubyists
 
Software Design Trilogy Part I - Responsibility Driven Design for Rubyists
Software Design Trilogy Part I - Responsibility Driven Design for RubyistsSoftware Design Trilogy Part I - Responsibility Driven Design for Rubyists
Software Design Trilogy Part I - Responsibility Driven Design for Rubyists
 
Simplifying Desktop Development With Glimmer
Simplifying Desktop Development With GlimmerSimplifying Desktop Development With Glimmer
Simplifying Desktop Development With Glimmer
 

Recently uploaded

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 

Recently uploaded (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 

Rails Engine Patterns

  • 1.
  • 2. Problem Difficulty reusing functionality cutting across: Models Views Controllers Assets (JS, CSS, Images) Duplication across all web application layers.
  • 3. Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
  • 4. Solution Break common behavior into Rails Engines Customize models/controllers/helpers in each project where needed by reopening classes Customize Rails views in each project as needed by overriding templates Link to Rails Engines in Gemfile via Git repo
  • 5. Example Common Domain Rails Engine Search Map Rails Engine High School Public Athlete Recruiting Profiles Recruiting Rails App Rails App Rails App
  • 6. Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
  • 7. Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
  • 8. What is a Rails Engine? Ruby Gem + MVC stack elements
  • 9. What is a Rails Engine? Rails Engines let applications reuse: Models / Views / Controllers / Helpers Assets (JS, CSS, Images) Routes Rake tasks Generators
  • 10. What is a Rails Engine? Rails Engines let applications reuse: Initializers RSpec / Cucumber Rack application with middleware stack Migrations and seed data Libraries
  • 11. Engine Definition An engine structure is similar to a Rails app having app, config, lib, spec, features, etc… lib/engine_name.rb (read online instructions) lib/engine_name/engine.rb (read online instructions) To reuse engine, use “jeweler” gem to generate gemspec (read online instructions)
  • 14. Engine Consumption Reference engine via Gemfile as a Ruby gem or Git repo hosted gemified project: Courtesy of © 2002-2011 National Collegiate Scouting Association - All Rights Reserved
  • 15. Load Order Typically Rails app files load first before Engine files. Strongly recommended to reverse so that engine’s code is customizable in app
  • 16. Load Order Reversing load order can happen in one of two ways: Patching “active_support/dependencies.rb” in Rails 3.1- (see next slide) Adjusting railties_order in Rails 3.2+
  • 17.
  • 18. Ruby Code Customization Model/Helper/Controller behavior can be customized be redefining .rb files in Rails App Customizations get mixed in with files in Engine This allows: Adding new methods/behavior Replacing existing methods Extending existing methods (alias_method_chain)
  • 21. View and Asset Customization Engine View and Asset presentation can be customized by redefining files in Rails App Customizations completely override files in Engine Examples of customizable View and Asset files: ERB/Haml JS CSS Images
  • 24. Recommended Engine Code Management • Each Engine lives in own Repo independent of Rails App • Each Engine has its own Gem dependencies (Gemfile) • Engines preferably share the same Ruby version as Rails App
  • 25. Typical Development Process 1. Make changes in engine, rake, and commit obtaining a new GIT ref 2. Update Gemfile in app with new git ref, run “bundle install” (getting ride of symlink) 3. Rake and commit changes in app. 4. If more changes in engine are needed go back to step 1
  • 26. Improved Productivity via Symlinking Multiple engine dependencies can hamper productivity when frequently going back and forth between engines and app Engine gems installed via bundler can be symlinked to allow continuous development until done with both app and engine:http://andymaleh.blogspot.com/2011/09/ more-productive-rails-engine.html
  • 27. Improved Development Process 1. Open Rails app and symlink all engines “rake engine:symlink[engine_name]” 2. Work in app and engine until done WITHOUT running “bundle install” 3. Rake and commit changes in engine obtaining a new git ref 4. Update Gemfile in app with git ref, run “bundle install” (getting ride of symlink) 5. Rake and commit changes in app
  • 28. Engines Reuse Engines Rails engines can reuse other Rails engines Common Domain Rails Engine Search Map Rails Engine High School Public Athlete Recruiting Profiles Recruiting Rails App Rails App Rails App
  • 29. Engines Reuse Engines When multiple levels of depth are involved, commit repos and update Gemfile from the bottom up Example: Engine 2 => Engine 1 => App 1. Commit in Engine 2 2. Update Gemfile in Engine 1 and commit 3. Update Gemfile in App and commit
  • 30. Engine Configuration Engines can be configured to customize rack middleware, load paths, generators, and Rails component paths. More details at: http://edgeapi.rubyonrails.org/classes/Rails/Engi ne.html
  • 31. Isolated Engines To avoid Ruby namespace clash with Models/Helpers/Controllers, you can define an isolated namespaced engine. For more details, go to http://edgeapi.rubyonrails.org/classes/Rails/Engi ne.html
  • 32. Rails Engine Patterns Goals: Keep engine code agnostic of app customizations Prevent bi-directional coupling to simplify reasoning about code Avoid app dependent conditionals to improve code maintainability
  • 33. Pattern - Common Domain Problem: Multiple Rails Apps need to share a basic domain model including default CRUD and presentation behavior Example: need to reuse address model and form entry behavior
  • 34. Pattern - Common Domain Solution: In engine, include basic domain models (base behavior, common associations) with their views, CRUD controllers, and routes. In each app, define domain model specialized behavior, extra associations, and custom views Make sure routes are declared with Rails.application.routes.draw (not Rails App name)
  • 35. Pattern - Common Domain Example: address.rb, addresses_controller.rb, address route, and _address.html.erb
  • 36. Pattern - Expose Helper Problem: need to customize presentation logic for a view in one app only, but keep the same logic in others Example: One App needs to hide address1 and county for non- government users. Other Apps wants to keep the fields displayed. You might start by overriding view, but then realize it is duplicating many elements just to hide a couple fields.
  • 37. Pattern - Expose Helper Solution: In Engine, extract helper logic that needs customization into its own helper. In App, redefine that new helper with customizations.
  • 38. Pattern - Expose Helper (view in Engine)
  • 39. Pattern - Expose Helper (trying to customize view in App)
  • 40. Pattern - Expose Helper Remove custom view from App Use requires_extended_address? helper in Engine wherever the App used government_user? In Engine, define requires_extended_address? to return true In App, define requires_extended_address? to return government_user?
  • 41. Pattern - Expose Helper (view + helper in Engine)
  • 42. Pattern - Expose Partial Problem: need to have different customizations in one part of the view in multiple apps Example: Address form One App needs an extra neighborhood field Another App needs an extra region field
  • 43. Pattern - Expose Partial Example App 1:
  • 44. Pattern - Expose Partial Example App 2:
  • 45. Pattern - Expose Partial Solution: In Engine, extract view part that needs customization as a partial. In App, redefine that partial with customizations.
  • 46. Pattern - Expose Partial Example: Define _address_extra_fields partial with empty content in Engine Redefine _address_extra_fields in Apps needing extra fields
  • 47. Pattern - Extension Point Problem: multiple Apps need to contribute data to a View in different places Example: multiple Apps need to add custom Rows in different spots of a List that comes from an Engine
  • 48. Pattern - Extension Point Engine defines only 3 elements in a list (About Me, News and Noteworthy) 1 2 3
  • 49. Pattern - Extension Point Solution: In Engine, add Helper logic that looks up partials in a specific ext directory, and based on file name (e.g. row_7.html.erb) insert into the right location in the View. In App, define these partials with the right file names and locations.
  • 50. Pattern - Extension Point App 1 adds “nav_bar_list_ext/_row_1.html.erb” 1 2 3 4
  • 51. Pattern - Extension Point App 2 adds “nav_bar_list_ext/_row_4.html.erb” 1 2 3 4
  • 52. Pattern - Configurable Features Problem: different apps need different features from an engine in different combinations
  • 53. Pattern - Configurable Features Solution: In Engine, add logic that looks up configuration options In App, configure Engine by overriding configuration options
  • 54. Pattern - Configurable Features Example: Engine defines engine_config.yml enable_address_extensions: true enable_address_headers: true App overrides some options in engine_config.yml Engine uses config options to customize behavior using conditionals
  • 55. Rails Engine Costs Overhead in establishing a new Rails Engine gem project Continuous switching between projects and engines to get work done Upgrade of ref numbers in Gemfile on every commit (minimized with symlinking)
  • 56. Rails Engine Benefits Code reuse across all application layers Better maintainability due to: Independent project codebases Cleanly defined boundaries between projects and reusable components (engines) Project tests get smaller and run faster
  • 57. Engines vs Services Engines are better when: Reusing small MVC features, especially domain independent (e.g. Search Map) Preferring to avoiding network and infrastructure overhead over establishing a service Wanting to quickly extract and reuse a feature
  • 58. Engines vs Services Web Services are better when: Reusing larger MVC features that depend on domain data Need to consume feature in another programming language or outside the organization boundaries Need to scale up feature performance independently of the application (e.g. separate DB)
  • 59. Engines vs Services To keep an easier to maintain Agile code base, start simple and then move incrementally towards a more complex architecture: Extract an MVC feature as an engine first Convert engine into a service when the need arises
  • 61. Review Basics of Rails Engines Rails Engine Patterns Improved Productivity Tips Summary of Benefits and Trade-Offs
  • 62. More Info http://edgeapi.rubyonrails.org/classes/Rails/Engi ne.html http://andymaleh.blogspot.com/2011/09/more- productive-rails-engine.html http://stackoverflow.com/questions/2964050/rail s-engines-extending- functionality/2990539#2990539
  • 63. Contact Andy Maleh / Software Engineer / Groupon Email: amaleh {at} groupon {dot} com Code Painter Blog: http://andymaleh.blogspot.com Twitter: @AndyMaleh