SlideShare a Scribd company logo
1 of 57
Download to read offline
feature flagging
with Ruby on Rails engines
Enrico Teotti -- @agenteo
admin user interface
public user interface
domain logic
requirement
run the private and public portions of the app
on separate servers
service oriented architecture
first proposal
two apps sharing components via engines
second proposal
local rails engines components
third proposal
public_uiadmin_ui
Rails.application.routes.draw do
case AppRunningMode .value
when :admin
mount AdminUi::Engine => "/"
when :public
mount PublicUi::Engine => "/"
else
mount AdminUi::Engine => "/"
mount PublicUi::Engine => "/"
end
end
config/routes.rb
RUNNING_MODE=public rails
s
RUNNING_MODE=admin rails s
http://worldwideshipping-super-secret-domain.com/admin
http://worldwideshipping.com
rails s
http://localhost:3000
● are ruby gems
● are special ruby gems that provide extra
behaviour (models, views, routes, rake
tasks) to a Rails application
● they can be hosted on a gemserver or
they can live inside your repository
● can be tested in isolation
rails engines
admin user interface
public user interface
domain logic
mkdir components
rails plugin new admin_ui --mountable --dummy=spec/dummy -O -T
mv admin_ui components
admin user interface
public user interface
domain logic
admin_ui
proceeding without automated tests
could drive you crazy
shared user interface (preview)
shared domain
admin_ui
Rails.application.routes.draw do
# ... public routes here
mount AdminUi::Engine => "/"
end
config/routes.rb
gem 'admin_ui', path: 'components/admin_ui'
Gemfile
public user interface
admin_ui
public_ui
rails plugin new public_ui --mountable --dummy=spec/dummy -O -T
gem 'admin_ui', path: 'components/admin_ui'
gem 'public_ui', path: 'components/public_ui'
Gemfile
public_uiadmin_ui
Gem::Specification.new do |s|
# ... other fields up here
s.name = "public_ui"
s.add_dependency "rails", "~> 4.1.1"
s.add_dependency 'jquery-rails'
s.add_dependency 'mongoid'
s.add_runtime_dependency "admin_ui"
s.add_development_dependency'byebug'
s.add_development_dependency'database_cleaner'
s.add_development_dependency'rspec-rails', '2.99.0'
s.add_development_dependency'capybara'
s.add_development_dependency'poltergeist'
end
public_ui.gemspec
Gem::Specification.new do |s|
# ... other fields up here
s.name = "public_ui"
s.add_dependency "rails", "~> 4.1.1"
s.add_dependency 'jquery-rails'
s.add_dependency 'mongoid'
s.add_runtime_dependency "admin_ui"
s.add_development_dependency 'byebug'
s.add_development_dependency 'database_cleaner'
s.add_development_dependency 'rspec-rails', '2.99.0'
s.add_development_dependency 'capybara'
s.add_development_dependency 'poltergeist'
end
public_ui.gemspec
Rails.application.routes.draw do
case AppRunningMode .value
when :admin
mount AdminUi::Engine => "/"
when :public
mount PublicUi::Engine => "/"
else
mount AdminUi::Engine => "/"
mount PublicUi::Engine => "/"
end
end
config/routes.rb
the two engines are now glued together!
admin_ui public_ui
domain_logic
rails plugin new domain_logic --dummy-path=spec/dummy --mountable
-O -T
admin_ui public_ui
shared_ui domain_logic
rails plugin new shared_ui --dummy-path=spec/dummy --mountable -O
-T
<%= render partial: 'shared_ui/cargos/show' %>
admin_ui/app/views/cargo_preview/show.html.erb
<%# admin console stuff here %>
<%= render partial: 'shared_ui/cargos/show' %>
<%# admin spaceship here %>
public_ui/app/views/cargos/show.html.erb
gem 'domain_logic' , path: 'components/domain_logic'
gem 'shared_ui', path: 'components/shared_ui'
gem 'admin_ui', path: 'components/admin_ui'
gem 'public_ui', path: 'components/public_ui'
Gemfile
#gem 'domain_logic', path: 'components/domain_logic'
#gem 'shared_ui', path: 'components/shared_ui'
gem 'admin_ui', path: 'components/admin_ui'
gem 'public_ui', path: 'components/public_ui'
Gemfile
$ bundle
Resolving dependencies...
Could not find gem 'shared_ui (>= 0) ruby', which is required by
gem 'admin_ui (>= 0) ruby', in any of the sources.
common pitfalls in Rails engines land
Gem::Specification.new do |s|
# ... other fields up here
s.name = "admin_ui"
s.add_dependency "rails", "~> 4.1.1"
s.add_dependency 'jquery-rails'
s.add_dependency 'mongoid'
s.add_dependency 'faraday'
s.add_dependency "domain_logic"
s.add_dependency "shared_ui"
s.add_development_dependency'byebug'
s.add_development_dependency'database_cleaner'
s.add_development_dependency'rspec-rails', '2.99.0'
s.add_development_dependency'vcr'
s.add_development_dependency'webmock'
s.add_development_dependency'capybara'
s.add_development_dependency'poltergeist'
end
admin_ui.gemspec
Gem::Specification.new do |s|
# ... other fields up here
s.name = "admin_ui"
s.add_dependency "rails", "~> 4.1.1"
s.add_dependency 'jquery-rails'
s.add_dependency 'mongoid'
s.add_dependency 'faraday'
s.add_dependency "domain_logic"
s.add_dependency "shared_ui"
s.add_development_dependency 'byebug'
s.add_development_dependency 'database_cleaner'
s.add_development_dependency 'rspec-rails', '2.99.0'
s.add_development_dependency 'vcr'
s.add_development_dependency 'webmock'
s.add_development_dependency 'capybara'
s.add_development_dependency 'poltergeist'
end
admin_ui/admin_ui.gemspec
source "https://rubygems.org"
gem 'domain_logic', path: '../domain_logic'
gem 'shared_ui', path: '../shared_ui'
# Declare your gem's dependencies in admin_ui.gemspec.
# Bundler will treat runtime dependencies like base
dependencies, and
# development dependencies will be added by default to
the :development group.
gemspec
admin_ui/Gemfile
require
the test dummy app
require File.expand_path("../dummy/config/environment", __FILE__)
admin_ui/spec/rails_helper.rb
admin_ui/spec/dummy/config/boot.rb
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
$LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
Rails.application.routes.draw do
mount AdminUi::Engine => "/admin_ui"
end
admin_ui/spec /dummy/config/routes.rb
Rails.application.routes.draw do
mount AdminUi::Engine => "/admin_ui"
end
admin_ui/spec /dummy/config/routes.rb
testing multiple engines
#!/bin/bash
unset BUNDLE_GEMFILE
result=0
if [ "$CI" == "true" ]; then
BUNDLE_PATH="$HOME/vendor/bundle"
fi
for test_script in $(find . -name test.sh); do
pushd `dirname $test_script` > /dev/null
./test.sh
result+=$?
popd > /dev/null
done
if [ $result -eq 0 ]; then
echo "SUCCESS"
else
echo "FAILURE"
fi
exit $result
https://github.com/shageman/the_next_big_thing/blob/master/build.sh
require_dependency "admin_ui/application_controller"
module AdminUi
class CargosController < ApplicationController
module AdminUi
class CargosController < AdminUi::ApplicationController
module AdminUi
class VoyagesController < ApplicationController
module AdminUi
class VoyagesController < ApplicationController
scaffolding and other generators
rails generate scaffold_controller admin_ui/cargo source
destination weight --model-name=DomainLogic::Cargo --orm=mongoid
-t=''
require_dependency "admin_ui/domain_logic/application_controller"
Failures:
1) Staff booking a cargo booking a cargo fitting a pending voyage
Failure/Error: visit '/admin/cargos'
LoadError:
No such file to load -- admin_ui/domain_logic/application_controller
# ./engines/admin_ui/app/controllers/admin_ui/cargos_controller.rb:1:in `<top (required)>'
# ./spec/features/book_cargo_spec.rb:12:in `block (2 levels) in <top (required)>'
Finished in 0.03067 seconds (files took 1.85 seconds to load)
2 examples, 1 failure
Failures:
1) Staff booking a cargo booking a cargo fitting a pending voyage
Failure/Error: visit '/admin/cargos'
RuntimeError:
Circular dependency detectedwhile autoloading constant AdminUi::AdminUi::CargosHelper
# ./engines/admin_ui/app/controllers/admin_ui/application_controller.rb:2:in `<module:AdminUi>'
# ./engines/admin_ui/app/controllers/admin_ui/application_controller.rb:1:in `<top (required)>'
# ./engines/admin_ui/app/controllers/admin_ui/cargos_controller.rb:1:in `<top (required)>'
# ./spec/features/book_cargo_spec.rb:12:in `block (2 levels) in <top (required)>'
Failures:
1) Staff booking a cargo booking a cargo fitting a pending voyage
Failure/Error: visit '/admin/cargos'
ActionView::Template::Error:
undefined local variable or method `new_domain_logic_cargo_path' for #<#<Class:0x007fb38887bb38>:
0x007fb388873690>
# ./engines/admin_ui/app/views/admin_ui/cargos/index.html.erb:29:in
`_engines_admin_ui_app_views_admin_ui_cargos_index_html_erb__4343322268368929370_70204533119300'
# ./spec/features/book_cargo_spec.rb:12:in `block (2 levels) in <top (required)>'
fang:domain_logic agenteo$ rails generate mongoid:config
/Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/mongoid-4.0.0/lib/rails/generators /mongoid/config/config_generator.rb: 16:in
`app_name': undefined method `parent' for nil:NilClass (NoMethodError)
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/command.rb: 27:in `run'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 126:in `invoke_command'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `block in invoke_all'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `each'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `map'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `invoke_all'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/group.rb: 232:in `dispatch'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/base.rb: 440:in `start'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/generators.rb: 157:in `invoke'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/commands /generate.rb: 11:in `<top (required)
>'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/engine/commands.rb: 19:in `require'
from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/engine/commands.rb: 19:in `<top (required) >'
from bin/rails:12:in `require'
from bin/rails:12:in `<main>'
FOLLOWUP READS
http://guides.rubyonrails.org/engines.html
http://pivotallabs.com/tag/cobra/
https://leanpub.com/cobra
http://teotti.com
Enrico Teotti @agenteo enrico@teotti.com

More Related Content

What's hot

Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - WisemblySymfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - WisemblyGuillaume POTIER
 
Liferay Devcon presentation on Workflow & Dynamic Forms
Liferay Devcon presentation on Workflow & Dynamic FormsLiferay Devcon presentation on Workflow & Dynamic Forms
Liferay Devcon presentation on Workflow & Dynamic FormsWillem Vermeer
 
Hastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoHastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoMaxime Najim
 
6applets And Graphics
6applets And Graphics6applets And Graphics
6applets And GraphicsAdil Jafri
 
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsCustom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsAkhil Mittal
 
Ruby on Rails na Unip
Ruby on Rails na UnipRuby on Rails na Unip
Ruby on Rails na UnipFabio Akita
 
Baruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion WorkshopBaruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion WorkshopBrian Sam-Bodden
 
What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018Somkiat Khitwongwattana
 
Kaleo workflow in Liferay
Kaleo workflow in LiferayKaleo workflow in Liferay
Kaleo workflow in LiferayWillem Vermeer
 
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataIn The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataStacy London
 
WAC Network APIs @ OverTheAir 2011
WAC Network APIs @ OverTheAir 2011WAC Network APIs @ OverTheAir 2011
WAC Network APIs @ OverTheAir 2011Ricardo Varela
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP pluginsPierre MARTIN
 
Refactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.jsRefactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.jsStacy London
 
Rails 6 frontend frameworks
Rails 6 frontend frameworksRails 6 frontend frameworks
Rails 6 frontend frameworksEric Guo
 
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W... 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...Robert Nyman
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-IIIprinceirfancivil
 
Web components with Angular
Web components with AngularWeb components with Angular
Web components with AngularAna Cidre
 

What's hot (20)

Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 
Android swedroid
Android swedroidAndroid swedroid
Android swedroid
 
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - WisemblySymfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
 
Liferay Devcon presentation on Workflow & Dynamic Forms
Liferay Devcon presentation on Workflow & Dynamic FormsLiferay Devcon presentation on Workflow & Dynamic Forms
Liferay Devcon presentation on Workflow & Dynamic Forms
 
Hastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoHastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San Diego
 
6applets And Graphics
6applets And Graphics6applets And Graphics
6applets And Graphics
 
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsCustom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs
 
Ruby on Rails na Unip
Ruby on Rails na UnipRuby on Rails na Unip
Ruby on Rails na Unip
 
Baruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion WorkshopBaruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion Workshop
 
What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018
 
Kaleo workflow in Liferay
Kaleo workflow in LiferayKaleo workflow in Liferay
Kaleo workflow in Liferay
 
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataIn The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
 
WAC Network APIs @ OverTheAir 2011
WAC Network APIs @ OverTheAir 2011WAC Network APIs @ OverTheAir 2011
WAC Network APIs @ OverTheAir 2011
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
 
Refactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.jsRefactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.js
 
Rails 6 frontend frameworks
Rails 6 frontend frameworksRails 6 frontend frameworks
Rails 6 frontend frameworks
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
 
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W... 	Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
Bringing the open web and APIs to mobile devices with Firefox OS - Whisky W...
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-III
 
Web components with Angular
Web components with AngularWeb components with Angular
Web components with Angular
 

Similar to Feature flagging with rails engines

Lightening a component based Rails architecture
Lightening a component based Rails architectureLightening a component based Rails architecture
Lightening a component based Rails architectureEnrico Teotti
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing optionsNir Kaufman
 
A Story about AngularJS modularization development
A Story about AngularJS modularization developmentA Story about AngularJS modularization development
A Story about AngularJS modularization developmentJohannes Weber
 
Symfony2 for Midgard Developers
Symfony2 for Midgard DevelopersSymfony2 for Midgard Developers
Symfony2 for Midgard DevelopersHenri Bergius
 
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 Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular applicationmirrec
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowVrann Tulika
 
Building a dashboard using AngularJS
Building a dashboard using AngularJSBuilding a dashboard using AngularJS
Building a dashboard using AngularJSRajthilakMCA
 
Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2Sumy PHP User Grpoup
 
Creating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 ComponentsCreating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 ComponentsDeepak Chandani
 
Desymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesDesymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesAlbert Jessurum
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascriptaglemann
 
Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8Skilld
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Plug it on!... with railties
Plug it on!... with railtiesPlug it on!... with railties
Plug it on!... with railtiesrails.mx
 
Laravel development (Laravel History, Environment Setup & Laravel Installatio...
Laravel development (Laravel History, Environment Setup & Laravel Installatio...Laravel development (Laravel History, Environment Setup & Laravel Installatio...
Laravel development (Laravel History, Environment Setup & Laravel Installatio...Dilouar Hossain
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'sAntônio Roberto Silva
 

Similar to Feature flagging with rails engines (20)

Lightening a component based Rails architecture
Lightening a component based Rails architectureLightening a component based Rails architecture
Lightening a component based Rails architecture
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
A Story about AngularJS modularization development
A Story about AngularJS modularization developmentA Story about AngularJS modularization development
A Story about AngularJS modularization development
 
Symfony2 for Midgard Developers
Symfony2 for Midgard DevelopersSymfony2 for Midgard Developers
Symfony2 for Midgard Developers
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
Building a dashboard using AngularJS
Building a dashboard using AngularJSBuilding a dashboard using AngularJS
Building a dashboard using AngularJS
 
Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2
 
Creating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 ComponentsCreating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 Components
 
Desymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesDesymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus Bundles
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascript
 
Rails::Engine
Rails::EngineRails::Engine
Rails::Engine
 
Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Rails engines
Rails enginesRails engines
Rails engines
 
Plug it on!... with railties
Plug it on!... with railtiesPlug it on!... with railties
Plug it on!... with railties
 
Laravel development (Laravel History, Environment Setup & Laravel Installatio...
Laravel development (Laravel History, Environment Setup & Laravel Installatio...Laravel development (Laravel History, Environment Setup & Laravel Installatio...
Laravel development (Laravel History, Environment Setup & Laravel Installatio...
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 

More from Enrico Teotti

Facilitating an online Agile Retrospective.pdf
Facilitating an online Agile Retrospective.pdfFacilitating an online Agile Retrospective.pdf
Facilitating an online Agile Retrospective.pdfEnrico Teotti
 
Build and maintain large Ruby applications 2023
Build and maintain large Ruby applications 2023Build and maintain large Ruby applications 2023
Build and maintain large Ruby applications 2023Enrico Teotti
 
Facilitating online agile retrospectives
Facilitating online agile retrospectivesFacilitating online agile retrospectives
Facilitating online agile retrospectivesEnrico Teotti
 
Measure success in agile retrospectives
Measure success in agile retrospectivesMeasure success in agile retrospectives
Measure success in agile retrospectivesEnrico Teotti
 
Build and maintain large ruby applications - LA Ruby Oct meetup
Build and maintain large ruby applications - LA Ruby Oct meetupBuild and maintain large ruby applications - LA Ruby Oct meetup
Build and maintain large ruby applications - LA Ruby Oct meetupEnrico Teotti
 
3 things about public speaking
3 things about public speaking3 things about public speaking
3 things about public speakingEnrico Teotti
 
Build and maintain large ruby applications Ruby Conf Australia 2016
Build and maintain large ruby applications Ruby Conf Australia 2016Build and maintain large ruby applications Ruby Conf Australia 2016
Build and maintain large ruby applications Ruby Conf Australia 2016Enrico Teotti
 
Build and maintain large Ruby apps 0.0.1
Build and maintain large Ruby apps 0.0.1Build and maintain large Ruby apps 0.0.1
Build and maintain large Ruby apps 0.0.1Enrico Teotti
 
Rails engines in large apps
Rails engines in large appsRails engines in large apps
Rails engines in large appsEnrico Teotti
 

More from Enrico Teotti (11)

Facilitating an online Agile Retrospective.pdf
Facilitating an online Agile Retrospective.pdfFacilitating an online Agile Retrospective.pdf
Facilitating an online Agile Retrospective.pdf
 
Build and maintain large Ruby applications 2023
Build and maintain large Ruby applications 2023Build and maintain large Ruby applications 2023
Build and maintain large Ruby applications 2023
 
Facilitating online agile retrospectives
Facilitating online agile retrospectivesFacilitating online agile retrospectives
Facilitating online agile retrospectives
 
Measure success in agile retrospectives
Measure success in agile retrospectivesMeasure success in agile retrospectives
Measure success in agile retrospectives
 
Structured retros
Structured retrosStructured retros
Structured retros
 
Build and maintain large ruby applications - LA Ruby Oct meetup
Build and maintain large ruby applications - LA Ruby Oct meetupBuild and maintain large ruby applications - LA Ruby Oct meetup
Build and maintain large ruby applications - LA Ruby Oct meetup
 
3 things about public speaking
3 things about public speaking3 things about public speaking
3 things about public speaking
 
Build and maintain large ruby applications Ruby Conf Australia 2016
Build and maintain large ruby applications Ruby Conf Australia 2016Build and maintain large ruby applications Ruby Conf Australia 2016
Build and maintain large ruby applications Ruby Conf Australia 2016
 
Build and maintain large Ruby apps 0.0.1
Build and maintain large Ruby apps 0.0.1Build and maintain large Ruby apps 0.0.1
Build and maintain large Ruby apps 0.0.1
 
Mindset
MindsetMindset
Mindset
 
Rails engines in large apps
Rails engines in large appsRails engines in large apps
Rails engines in large apps
 

Recently uploaded

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
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
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
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
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

Feature flagging with rails engines

  • 1. feature flagging with Ruby on Rails engines Enrico Teotti -- @agenteo
  • 2. admin user interface public user interface domain logic
  • 3. requirement run the private and public portions of the app on separate servers
  • 5. two apps sharing components via engines second proposal
  • 6. local rails engines components third proposal
  • 8. Rails.application.routes.draw do case AppRunningMode .value when :admin mount AdminUi::Engine => "/" when :public mount PublicUi::Engine => "/" else mount AdminUi::Engine => "/" mount PublicUi::Engine => "/" end end config/routes.rb
  • 9. RUNNING_MODE=public rails s RUNNING_MODE=admin rails s http://worldwideshipping-super-secret-domain.com/admin http://worldwideshipping.com rails s http://localhost:3000
  • 10. ● are ruby gems ● are special ruby gems that provide extra behaviour (models, views, routes, rake tasks) to a Rails application ● they can be hosted on a gemserver or they can live inside your repository ● can be tested in isolation rails engines
  • 11. admin user interface public user interface domain logic
  • 13. rails plugin new admin_ui --mountable --dummy=spec/dummy -O -T mv admin_ui components
  • 14. admin user interface public user interface domain logic admin_ui
  • 15. proceeding without automated tests could drive you crazy
  • 16. shared user interface (preview) shared domain admin_ui
  • 17. Rails.application.routes.draw do # ... public routes here mount AdminUi::Engine => "/" end config/routes.rb
  • 18. gem 'admin_ui', path: 'components/admin_ui' Gemfile
  • 20. rails plugin new public_ui --mountable --dummy=spec/dummy -O -T
  • 21. gem 'admin_ui', path: 'components/admin_ui' gem 'public_ui', path: 'components/public_ui' Gemfile
  • 23. Gem::Specification.new do |s| # ... other fields up here s.name = "public_ui" s.add_dependency "rails", "~> 4.1.1" s.add_dependency 'jquery-rails' s.add_dependency 'mongoid' s.add_runtime_dependency "admin_ui" s.add_development_dependency'byebug' s.add_development_dependency'database_cleaner' s.add_development_dependency'rspec-rails', '2.99.0' s.add_development_dependency'capybara' s.add_development_dependency'poltergeist' end public_ui.gemspec
  • 24. Gem::Specification.new do |s| # ... other fields up here s.name = "public_ui" s.add_dependency "rails", "~> 4.1.1" s.add_dependency 'jquery-rails' s.add_dependency 'mongoid' s.add_runtime_dependency "admin_ui" s.add_development_dependency 'byebug' s.add_development_dependency 'database_cleaner' s.add_development_dependency 'rspec-rails', '2.99.0' s.add_development_dependency 'capybara' s.add_development_dependency 'poltergeist' end public_ui.gemspec
  • 25. Rails.application.routes.draw do case AppRunningMode .value when :admin mount AdminUi::Engine => "/" when :public mount PublicUi::Engine => "/" else mount AdminUi::Engine => "/" mount PublicUi::Engine => "/" end end config/routes.rb
  • 26. the two engines are now glued together!
  • 28. rails plugin new domain_logic --dummy-path=spec/dummy --mountable -O -T
  • 30. rails plugin new shared_ui --dummy-path=spec/dummy --mountable -O -T
  • 31. <%= render partial: 'shared_ui/cargos/show' %> admin_ui/app/views/cargo_preview/show.html.erb <%# admin console stuff here %> <%= render partial: 'shared_ui/cargos/show' %> <%# admin spaceship here %> public_ui/app/views/cargos/show.html.erb
  • 32. gem 'domain_logic' , path: 'components/domain_logic' gem 'shared_ui', path: 'components/shared_ui' gem 'admin_ui', path: 'components/admin_ui' gem 'public_ui', path: 'components/public_ui' Gemfile
  • 33. #gem 'domain_logic', path: 'components/domain_logic' #gem 'shared_ui', path: 'components/shared_ui' gem 'admin_ui', path: 'components/admin_ui' gem 'public_ui', path: 'components/public_ui' Gemfile
  • 34. $ bundle Resolving dependencies... Could not find gem 'shared_ui (>= 0) ruby', which is required by gem 'admin_ui (>= 0) ruby', in any of the sources.
  • 35. common pitfalls in Rails engines land
  • 36. Gem::Specification.new do |s| # ... other fields up here s.name = "admin_ui" s.add_dependency "rails", "~> 4.1.1" s.add_dependency 'jquery-rails' s.add_dependency 'mongoid' s.add_dependency 'faraday' s.add_dependency "domain_logic" s.add_dependency "shared_ui" s.add_development_dependency'byebug' s.add_development_dependency'database_cleaner' s.add_development_dependency'rspec-rails', '2.99.0' s.add_development_dependency'vcr' s.add_development_dependency'webmock' s.add_development_dependency'capybara' s.add_development_dependency'poltergeist' end admin_ui.gemspec
  • 37. Gem::Specification.new do |s| # ... other fields up here s.name = "admin_ui" s.add_dependency "rails", "~> 4.1.1" s.add_dependency 'jquery-rails' s.add_dependency 'mongoid' s.add_dependency 'faraday' s.add_dependency "domain_logic" s.add_dependency "shared_ui" s.add_development_dependency 'byebug' s.add_development_dependency 'database_cleaner' s.add_development_dependency 'rspec-rails', '2.99.0' s.add_development_dependency 'vcr' s.add_development_dependency 'webmock' s.add_development_dependency 'capybara' s.add_development_dependency 'poltergeist' end admin_ui/admin_ui.gemspec
  • 38. source "https://rubygems.org" gem 'domain_logic', path: '../domain_logic' gem 'shared_ui', path: '../shared_ui' # Declare your gem's dependencies in admin_ui.gemspec. # Bundler will treat runtime dependencies like base dependencies, and # development dependencies will be added by default to the :development group. gemspec admin_ui/Gemfile
  • 41. require File.expand_path("../dummy/config/environment", __FILE__) admin_ui/spec/rails_helper.rb admin_ui/spec/dummy/config/boot.rb # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) Rails.application.routes.draw do mount AdminUi::Engine => "/admin_ui" end admin_ui/spec /dummy/config/routes.rb
  • 42. Rails.application.routes.draw do mount AdminUi::Engine => "/admin_ui" end admin_ui/spec /dummy/config/routes.rb
  • 44. #!/bin/bash unset BUNDLE_GEMFILE result=0 if [ "$CI" == "true" ]; then BUNDLE_PATH="$HOME/vendor/bundle" fi for test_script in $(find . -name test.sh); do pushd `dirname $test_script` > /dev/null ./test.sh result+=$? popd > /dev/null done if [ $result -eq 0 ]; then echo "SUCCESS" else echo "FAILURE" fi exit $result https://github.com/shageman/the_next_big_thing/blob/master/build.sh
  • 46. module AdminUi class CargosController < AdminUi::ApplicationController
  • 47. module AdminUi class VoyagesController < ApplicationController
  • 48. module AdminUi class VoyagesController < ApplicationController
  • 49. scaffolding and other generators
  • 50. rails generate scaffold_controller admin_ui/cargo source destination weight --model-name=DomainLogic::Cargo --orm=mongoid -t=''
  • 52. Failures: 1) Staff booking a cargo booking a cargo fitting a pending voyage Failure/Error: visit '/admin/cargos' LoadError: No such file to load -- admin_ui/domain_logic/application_controller # ./engines/admin_ui/app/controllers/admin_ui/cargos_controller.rb:1:in `<top (required)>' # ./spec/features/book_cargo_spec.rb:12:in `block (2 levels) in <top (required)>' Finished in 0.03067 seconds (files took 1.85 seconds to load) 2 examples, 1 failure
  • 53. Failures: 1) Staff booking a cargo booking a cargo fitting a pending voyage Failure/Error: visit '/admin/cargos' RuntimeError: Circular dependency detectedwhile autoloading constant AdminUi::AdminUi::CargosHelper # ./engines/admin_ui/app/controllers/admin_ui/application_controller.rb:2:in `<module:AdminUi>' # ./engines/admin_ui/app/controllers/admin_ui/application_controller.rb:1:in `<top (required)>' # ./engines/admin_ui/app/controllers/admin_ui/cargos_controller.rb:1:in `<top (required)>' # ./spec/features/book_cargo_spec.rb:12:in `block (2 levels) in <top (required)>'
  • 54. Failures: 1) Staff booking a cargo booking a cargo fitting a pending voyage Failure/Error: visit '/admin/cargos' ActionView::Template::Error: undefined local variable or method `new_domain_logic_cargo_path' for #<#<Class:0x007fb38887bb38>: 0x007fb388873690> # ./engines/admin_ui/app/views/admin_ui/cargos/index.html.erb:29:in `_engines_admin_ui_app_views_admin_ui_cargos_index_html_erb__4343322268368929370_70204533119300' # ./spec/features/book_cargo_spec.rb:12:in `block (2 levels) in <top (required)>'
  • 55. fang:domain_logic agenteo$ rails generate mongoid:config /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/mongoid-4.0.0/lib/rails/generators /mongoid/config/config_generator.rb: 16:in `app_name': undefined method `parent' for nil:NilClass (NoMethodError) from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/command.rb: 27:in `run' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 126:in `invoke_command' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `block in invoke_all' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `each' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `map' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/invocation.rb: 133:in `invoke_all' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/group.rb: 232:in `dispatch' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/thor-0.19.1/lib/thor/base.rb: 440:in `start' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/generators.rb: 157:in `invoke' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/commands /generate.rb: 11:in `<top (required) >' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/engine/commands.rb: 19:in `require' from /Users/agenteo/.rvm/gems/ruby-2.1.2@worldwide_shipping /gems/railties -4.1.4/lib/rails/engine/commands.rb: 19:in `<top (required) >' from bin/rails:12:in `require' from bin/rails:12:in `<main>'
  • 56.