SlideShare une entreprise Scribd logo
1  sur  29
Problem

 monolithic application

 no reusability

 slow tests

 bigger application, more mess
Possible solutions

 extract common functionality to modules

 create gems

 tie gem with rails application with railtie

 rails engine
What is a Gem ?

 packaged application or library
      code
      tests
      documentation
      gemspec
Creating gem

 bundle gem simplify                ├── Gemfile
                                     ├── LICENSE.txt
                                     ├── README.md
 structure                          ├── Rakefile
      code (lib/)                   ├── lib
                                     │ ├── simplify
      tests (test/ or spec/)        │ │ └── version.rb
      documentation (doc/ README)   │ └── simplify.rb
                                     └── simplify.gemspec
      executable files (bin/)

 information about gem
    simplify.gemspec
Releasing Gem

     change version

     run `bundle`

     commit changes

     run `rake release`

$ rake release
stupid_spam_protection 0.0.2 built to pkg/stupid_spam_protection-0.0.2.gem
Tagged v0.0.2
Pushed git commits and tags
Pushed stupid_spam_protection 0.0.2 to rubygems.org
in-memory testing with sqlite
spec/spec_helper.rb
require "active_record"
require "sqlite3”

ActiveRecord::Base.establish_connectio
n{
  :adapter => "sqlite3”,
  :database => ":memory:”
}

load "db/schema.rb"                      db/schema.rb
                                         ActiveRecord::Schema.define do
RSpec.configure do |config|               create_table "items", :force => true do |t|
 config.around do |example|                t.string "name”
  ActiveRecord::Base.transaction do        t.datetime "created_at", :null => false
   example.run                             t.datetime "updated_at", :null => false
   raise ActiveRecord::Rollback           end
  end
 end
end
testing with mysql
                       database
spec/spec_helper.rb

 begin
   ActiveRecord::Base.establish_connection(config)
 rescue
   ActiveRecord::Base.establish_connection(config.merge('database' => nil))
   ActiveRecord::Base.connection.create_database(config['database'], {
   :charset => 'utf8‟,
   :collation => 'utf8_unicode_ci‟})
 end                                   config = HashWithIndifferentAccess.new({
                                         :adapter => "mysql2",
 load "db/schema.rb"                     :host => "127.0.0.1",
                                         :username => "root",
 RSpec.configure do |config|             :password => "",
  # the same from previous slide         :database => ”database_name”
 end                                   })
Tie gem to Rails app
           Rails::Railtie
 extend Rails framework
    load all needed dependencies

 several hooks methods for all needs

require "wnm_support/railtie" if defined?(Rails)   lib/wnm_support.rb

module WnmSupport                                  lib/wnm_support/railtie.rb
 class Railtie < Rails::Railtie
  initializer "wnm_support.view_helpers" do
    ActionView::Base.send :include,
BoolToHuman
  end
 end
end
Railtie hooks 1

 Plugin hooks
     initializer
     generators
     rake_tasks
     console

  initializer "wnm_support.active_record_ext" do
    ActiveSupport.on_load(:active_record) do
          ActiveRecord::Base.send :include,
               WnmSupport::ActiveRecordExt::DestroyValidation
    end
  end
Railtie hooks 2

 Rails configuration hooks
      to_prepare (once in production, every request in development)
      before_initialize
      after_initialize
      app_middleware
      before_configuration
      before_eager_load
      generators
   config.to_prepare do
    AppController.send(:include,
   Controller::Authentication)
   end
What is Rails Engine ?

 every rails app is an engine
 Rails::Engine < Rails::Railtie
 all together
      gem skeleton
      railtie
      structure for app
      dummy app for testing
      assets
Engine walkthrough

 generate new engine

 basic commands

 testing

 mounting to host app

 overriding defaults
Generating Engine

 rails plugin new blorgh --mountable –
  full

 everything (assets, controller, models,
  views) are inside Blorgh namespace
    module Blorgh
     class Engine < ::Rails::Engine
      isolate_namespace Blorgh
     end
    end
Basics commands

 in root directory of the engine
      bundle
      rake
      rspec
      rails generate # generate code for engine

 in spec/dummy or test/dummy location
    rails console
    rails server
    rails generate # generate code for dummy app
Testing

      generally as in standard rails application

      engine is tested inside dummy app

      small problems with factory girl
           explicite model class in factory girl
           include routes for request tests
FactoryGirl.define do
 factory :user, :class => Blorgh ::User do
  sequence(:login) { |n| "admin_#{n}" }      RSpec.configure do |config|
  password "too_secret"                       config.include Blorgh ::Engine.routes.url_helper
  password_confirmation { password }         end
 end
end
Mounting Engine to host
        application
 Gemfile
    gem “blorgh”, :path => “~/Sites/blorgh”

 install migration
    `rake blorgh:install:migrations`

 load seeds data
    Blorgh::Engine.load_seed # in rails console

 require assets if needed
    *= require blorgh/application # assets/stylesheets/application.css

 mount to routes.rb
    mount Blorgh::Engine => "/blorgh"
Get to engine and get
             back
 routes to engine from host app
    prefix with engine name
    example engine “blorgh”
       <%= link_to “Users”, blorgh.users_path %>

 routes from engine to host app
    prefix with main_app
    example engine “blorgh”
       <%= link_to “Home page”,main_app.root_path %>
Overriding engine classes

       Controller, Model, etc.
            reopening classes
                 class_eval, module_eval

module MySite
 class Railtie < ::Rails::Railtie
  config.to_prepare do
    Dir["app/decorators/**/*.rb"].each do |path|
     load path                                     app/decorators/models/blorgh/article.rb
    end
  end                                              Blorgh::Article.class_eval do
 end                                                has_many :users, :class_name => „User'
end                                                end
Overriding engine views

 simple copy and paste view file that you want to
  override to the same location in host app
Application Modules with
        Rails Engine
 every new engine means new namespace

 application modules means for us more engines with
  same namespace

 inspiration from refinerycms
The same namespace
       different engines
 module Wnm                         module Wnm
  module Core                        module Pages
   class Engine < ::Rails::Engine     class Engine < ::Rails::Engine
    isolate_namespace Wnm              isolate_namespace Wnm
    engine_name :wnm_core              engine_name :wnm_pages
  end                                end
 end                                end



rake wnm_core:install:migrations     rake wnm_pages:install:migrations

Wnm::Core::Engine.load_seed          Wnm::Pages::Engine.load_seed



                 both are nested in `Wnm` namespace
Developing from local
           Production from git
   bundler does not allow to have same package from
    different sources in Gemfile

export LOAD_GEMS_FROM_LOCAL=1               .rvmrc

if ENV["LOAD_GEMS_FROM_LOCAL"] == "1"                             Gemfile
  gem "wnm_core", :path => "~/Sites/wnm_core"
  gem "wnm_pages", :path => "~/Sites/wnm_pages"
  gem "wnm_customers", :path => "~/Sites/wnm_customers"
else
  gem "wnm_core", :git => "git@…/wnm_core.git", :tag => "v1.0.0"
  gem "wnm_pages", :git => "git@…/wnm_pages.git", :tag => "v1.0.0"
  gem "wnm_customers", :git => "git@.../wnm_customers.git", :tag => "v1.0.0"
end
Deploying

 change LOAD_GEMS_FROM_LOCAL to 0 and run
  `bundle`

 commit and push

 `cap deploy`
Tips

 if you are overriding views heavily always prefix routes
  path with engine module name
<%= link_to page.name, wnm_page.page_path(page), :title => page.name %>


 use class methods instead of constants

 always write full path to class/module if it is in
  namespace
     ::ApplicationController instead of ApplicationController

 testing is essential
Why use Rails::Engine ?

   reusable code
        code
        hole application
        assets

   modular thinking

   gem with MVC

   faster test

   testing gem in dummy app infrastructure

   some well known engines
        devise, kaminari, refinerycms
Problems

 if you are bending engines weird thinks can happen

 a lot of weird errors
     application does not run in development mode from git
      sources
     tests passed, but in browser it is not running
     in browser it is running but tests are throwing exceptions

 overriding classes in host app

 helper methods from host app does not work in overridden
  views

 some things from documentation does not work at all
Why we did this like that ?

 a lot of our project are in general the same

 build core for site quickly
    “scaffold” for application

 rails engine is infrastructure for modular application

 we can have backend and frontend in the same
  application module
Sources

 http://guides.rubygems.org/what-is-a-gem/
 http://www.engineyard.com/blog/2010/extending-rails-3-with-railties/
 http://www.slideshare.net/AndyMaleh/rails-engine-patterns
 http://edgeguides.rubyonrails.org/engines.html
 http://edgeapi.rubyonrails.org/classes/Rails/Railtie.html
 http://edgeapi.rubyonrails.org/classes/Rails/Engine.html
 http://pivotallabs.com/users/shagemann/blog/articles/1994-migrating-
  from-a-single-rails-app-to-a-suite-of-rails-engines
 http://railscasts.com/episodes/301-extracting-a-ruby-gem
 http://railscasts.com/episodes/303-publishing-a-gem
 http://railscasts.com/episodes/277-mountable-engines

Contenu connexe

Tendances

Rails Engines as a way to Micro services
Rails Engines as a way to Micro servicesRails Engines as a way to Micro services
Rails Engines as a way to Micro servicesLucas Alencar
 
Ruby w/o Rails (Олександр Сімонов)
Ruby w/o Rails (Олександр Сімонов)Ruby w/o Rails (Олександр Сімонов)
Ruby w/o Rails (Олександр Сімонов)Fwdays
 
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
 
React.js for Rails Developers
React.js for Rails DevelopersReact.js for Rails Developers
React.js for Rails DevelopersArkency
 
How angularjs saves rails
How angularjs saves railsHow angularjs saves rails
How angularjs saves railsMichael He
 
React on rails v6.1 at LA Ruby, November 2016
React on rails v6.1 at LA Ruby, November 2016React on rails v6.1 at LA Ruby, November 2016
React on rails v6.1 at LA Ruby, November 2016Justin Gordon
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with LaravelMichael Peacock
 
AngularJS meets Rails
AngularJS meets RailsAngularJS meets Rails
AngularJS meets RailsElena Torró
 
Brief Introduction to Ember
Brief Introduction to EmberBrief Introduction to Ember
Brief Introduction to EmberVinay B
 
Building modular applications with JPMS and Layrry
Building modular applications with JPMS and LayrryBuilding modular applications with JPMS and Layrry
Building modular applications with JPMS and LayrryAndres Almiray
 
Laravel Restful API and AngularJS
Laravel Restful API and AngularJSLaravel Restful API and AngularJS
Laravel Restful API and AngularJSBlake Newman
 
How to dockerize rails application compose and rails tutorial
How to dockerize rails application compose and rails tutorialHow to dockerize rails application compose and rails tutorial
How to dockerize rails application compose and rails tutorialKaty Slemon
 
Web Development with Laravel 5
Web Development with Laravel 5Web Development with Laravel 5
Web Development with Laravel 5Soheil Khodayari
 

Tendances (20)

Rails Engines as a way to Micro services
Rails Engines as a way to Micro servicesRails Engines as a way to Micro services
Rails Engines as a way to Micro services
 
Ruby w/o Rails (Олександр Сімонов)
Ruby w/o Rails (Олександр Сімонов)Ruby w/o Rails (Олександр Сімонов)
Ruby w/o Rails (Олександр Сімонов)
 
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
 
Rails::Engine
Rails::EngineRails::Engine
Rails::Engine
 
React.js for Rails Developers
React.js for Rails DevelopersReact.js for Rails Developers
React.js for Rails Developers
 
How angularjs saves rails
How angularjs saves railsHow angularjs saves rails
How angularjs saves rails
 
React on rails v6.1 at LA Ruby, November 2016
React on rails v6.1 at LA Ruby, November 2016React on rails v6.1 at LA Ruby, November 2016
React on rails v6.1 at LA Ruby, November 2016
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with Laravel
 
AngularJS meets Rails
AngularJS meets RailsAngularJS meets Rails
AngularJS meets Rails
 
Brief Introduction to Ember
Brief Introduction to EmberBrief Introduction to Ember
Brief Introduction to Ember
 
Building modular applications with JPMS and Layrry
Building modular applications with JPMS and LayrryBuilding modular applications with JPMS and Layrry
Building modular applications with JPMS and Layrry
 
Laravel Restful API and AngularJS
Laravel Restful API and AngularJSLaravel Restful API and AngularJS
Laravel Restful API and AngularJS
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Laravel Introduction
Laravel IntroductionLaravel Introduction
Laravel Introduction
 
How to dockerize rails application compose and rails tutorial
How to dockerize rails application compose and rails tutorialHow to dockerize rails application compose and rails tutorial
How to dockerize rails application compose and rails tutorial
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
 
Intro to Laravel
Intro to LaravelIntro to Laravel
Intro to Laravel
 
Slim3 quick start
Slim3 quick startSlim3 quick start
Slim3 quick start
 
Curso rails
Curso railsCurso rails
Curso rails
 
Web Development with Laravel 5
Web Development with Laravel 5Web Development with Laravel 5
Web Development with Laravel 5
 

Similaire à Rails Engine | Modular application

Deploying configurable frontend web application containers
Deploying configurable frontend web application containersDeploying configurable frontend web application containers
Deploying configurable frontend web application containersJosé Moreira
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoasZeid Hassan
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发shaokun
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - IntroductionVagmi Mudumbai
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby TeamArto Artnik
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails DevsDiacode
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsMarcelo Pinheiro
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017Ayush Sharma
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppSmartLogic
 
Improving build solutions dependency management with webpack
Improving build solutions  dependency management with webpackImproving build solutions  dependency management with webpack
Improving build solutions dependency management with webpackNodeXperts
 

Similaire à Rails Engine | Modular application (20)

Deploying configurable frontend web application containers
Deploying configurable frontend web application containersDeploying configurable frontend web application containers
Deploying configurable frontend web application containers
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Capistrano
CapistranoCapistrano
Capistrano
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
RoR guide_p1
RoR guide_p1RoR guide_p1
RoR guide_p1
 
Generators
GeneratorsGenerators
Generators
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - Introduction
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability Systems
 
Cooking with Chef
Cooking with ChefCooking with Chef
Cooking with Chef
 
Rails engines
Rails enginesRails engines
Rails engines
 
RequireJS
RequireJSRequireJS
RequireJS
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017
 
Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Improving build solutions dependency management with webpack
Improving build solutions  dependency management with webpackImproving build solutions  dependency management with webpack
Improving build solutions dependency management with webpack
 

Dernier

EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 

Dernier (20)

EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 

Rails Engine | Modular application

  • 1.
  • 2. Problem  monolithic application  no reusability  slow tests  bigger application, more mess
  • 3. Possible solutions  extract common functionality to modules  create gems  tie gem with rails application with railtie  rails engine
  • 4. What is a Gem ?  packaged application or library  code  tests  documentation  gemspec
  • 5. Creating gem  bundle gem simplify ├── Gemfile ├── LICENSE.txt ├── README.md  structure ├── Rakefile  code (lib/) ├── lib │ ├── simplify  tests (test/ or spec/) │ │ └── version.rb  documentation (doc/ README) │ └── simplify.rb └── simplify.gemspec  executable files (bin/)  information about gem  simplify.gemspec
  • 6. Releasing Gem  change version  run `bundle`  commit changes  run `rake release` $ rake release stupid_spam_protection 0.0.2 built to pkg/stupid_spam_protection-0.0.2.gem Tagged v0.0.2 Pushed git commits and tags Pushed stupid_spam_protection 0.0.2 to rubygems.org
  • 7. in-memory testing with sqlite spec/spec_helper.rb require "active_record" require "sqlite3” ActiveRecord::Base.establish_connectio n{ :adapter => "sqlite3”, :database => ":memory:” } load "db/schema.rb" db/schema.rb ActiveRecord::Schema.define do RSpec.configure do |config| create_table "items", :force => true do |t| config.around do |example| t.string "name” ActiveRecord::Base.transaction do t.datetime "created_at", :null => false example.run t.datetime "updated_at", :null => false raise ActiveRecord::Rollback end end end end
  • 8. testing with mysql database spec/spec_helper.rb begin ActiveRecord::Base.establish_connection(config) rescue ActiveRecord::Base.establish_connection(config.merge('database' => nil)) ActiveRecord::Base.connection.create_database(config['database'], { :charset => 'utf8‟, :collation => 'utf8_unicode_ci‟}) end config = HashWithIndifferentAccess.new({ :adapter => "mysql2", load "db/schema.rb" :host => "127.0.0.1", :username => "root", RSpec.configure do |config| :password => "", # the same from previous slide :database => ”database_name” end })
  • 9. Tie gem to Rails app Rails::Railtie  extend Rails framework  load all needed dependencies  several hooks methods for all needs require "wnm_support/railtie" if defined?(Rails) lib/wnm_support.rb module WnmSupport lib/wnm_support/railtie.rb class Railtie < Rails::Railtie initializer "wnm_support.view_helpers" do ActionView::Base.send :include, BoolToHuman end end end
  • 10. Railtie hooks 1  Plugin hooks  initializer  generators  rake_tasks  console initializer "wnm_support.active_record_ext" do ActiveSupport.on_load(:active_record) do ActiveRecord::Base.send :include, WnmSupport::ActiveRecordExt::DestroyValidation end end
  • 11. Railtie hooks 2  Rails configuration hooks  to_prepare (once in production, every request in development)  before_initialize  after_initialize  app_middleware  before_configuration  before_eager_load  generators config.to_prepare do AppController.send(:include, Controller::Authentication) end
  • 12. What is Rails Engine ?  every rails app is an engine  Rails::Engine < Rails::Railtie  all together  gem skeleton  railtie  structure for app  dummy app for testing  assets
  • 13. Engine walkthrough  generate new engine  basic commands  testing  mounting to host app  overriding defaults
  • 14. Generating Engine  rails plugin new blorgh --mountable – full  everything (assets, controller, models, views) are inside Blorgh namespace module Blorgh class Engine < ::Rails::Engine isolate_namespace Blorgh end end
  • 15. Basics commands  in root directory of the engine  bundle  rake  rspec  rails generate # generate code for engine  in spec/dummy or test/dummy location  rails console  rails server  rails generate # generate code for dummy app
  • 16. Testing  generally as in standard rails application  engine is tested inside dummy app  small problems with factory girl  explicite model class in factory girl  include routes for request tests FactoryGirl.define do factory :user, :class => Blorgh ::User do sequence(:login) { |n| "admin_#{n}" } RSpec.configure do |config| password "too_secret" config.include Blorgh ::Engine.routes.url_helper password_confirmation { password } end end end
  • 17. Mounting Engine to host application  Gemfile  gem “blorgh”, :path => “~/Sites/blorgh”  install migration  `rake blorgh:install:migrations`  load seeds data  Blorgh::Engine.load_seed # in rails console  require assets if needed  *= require blorgh/application # assets/stylesheets/application.css  mount to routes.rb  mount Blorgh::Engine => "/blorgh"
  • 18. Get to engine and get back  routes to engine from host app  prefix with engine name  example engine “blorgh”  <%= link_to “Users”, blorgh.users_path %>  routes from engine to host app  prefix with main_app  example engine “blorgh”  <%= link_to “Home page”,main_app.root_path %>
  • 19. Overriding engine classes  Controller, Model, etc.  reopening classes  class_eval, module_eval module MySite class Railtie < ::Rails::Railtie config.to_prepare do Dir["app/decorators/**/*.rb"].each do |path| load path app/decorators/models/blorgh/article.rb end end Blorgh::Article.class_eval do end has_many :users, :class_name => „User' end end
  • 20. Overriding engine views  simple copy and paste view file that you want to override to the same location in host app
  • 21. Application Modules with Rails Engine  every new engine means new namespace  application modules means for us more engines with same namespace  inspiration from refinerycms
  • 22. The same namespace different engines module Wnm module Wnm module Core module Pages class Engine < ::Rails::Engine class Engine < ::Rails::Engine isolate_namespace Wnm isolate_namespace Wnm engine_name :wnm_core engine_name :wnm_pages end end end end rake wnm_core:install:migrations rake wnm_pages:install:migrations Wnm::Core::Engine.load_seed Wnm::Pages::Engine.load_seed both are nested in `Wnm` namespace
  • 23. Developing from local Production from git  bundler does not allow to have same package from different sources in Gemfile export LOAD_GEMS_FROM_LOCAL=1 .rvmrc if ENV["LOAD_GEMS_FROM_LOCAL"] == "1" Gemfile gem "wnm_core", :path => "~/Sites/wnm_core" gem "wnm_pages", :path => "~/Sites/wnm_pages" gem "wnm_customers", :path => "~/Sites/wnm_customers" else gem "wnm_core", :git => "git@…/wnm_core.git", :tag => "v1.0.0" gem "wnm_pages", :git => "git@…/wnm_pages.git", :tag => "v1.0.0" gem "wnm_customers", :git => "git@.../wnm_customers.git", :tag => "v1.0.0" end
  • 24. Deploying  change LOAD_GEMS_FROM_LOCAL to 0 and run `bundle`  commit and push  `cap deploy`
  • 25. Tips  if you are overriding views heavily always prefix routes path with engine module name <%= link_to page.name, wnm_page.page_path(page), :title => page.name %>  use class methods instead of constants  always write full path to class/module if it is in namespace  ::ApplicationController instead of ApplicationController  testing is essential
  • 26. Why use Rails::Engine ?  reusable code  code  hole application  assets  modular thinking  gem with MVC  faster test  testing gem in dummy app infrastructure  some well known engines  devise, kaminari, refinerycms
  • 27. Problems  if you are bending engines weird thinks can happen  a lot of weird errors  application does not run in development mode from git sources  tests passed, but in browser it is not running  in browser it is running but tests are throwing exceptions  overriding classes in host app  helper methods from host app does not work in overridden views  some things from documentation does not work at all
  • 28. Why we did this like that ?  a lot of our project are in general the same  build core for site quickly  “scaffold” for application  rails engine is infrastructure for modular application  we can have backend and frontend in the same application module
  • 29. Sources  http://guides.rubygems.org/what-is-a-gem/  http://www.engineyard.com/blog/2010/extending-rails-3-with-railties/  http://www.slideshare.net/AndyMaleh/rails-engine-patterns  http://edgeguides.rubyonrails.org/engines.html  http://edgeapi.rubyonrails.org/classes/Rails/Railtie.html  http://edgeapi.rubyonrails.org/classes/Rails/Engine.html  http://pivotallabs.com/users/shagemann/blog/articles/1994-migrating- from-a-single-rails-app-to-a-suite-of-rails-engines  http://railscasts.com/episodes/301-extracting-a-ruby-gem  http://railscasts.com/episodes/303-publishing-a-gem  http://railscasts.com/episodes/277-mountable-engines