learning environment. Lots of experience I am sharing today comes from building this platform. GeekMeet #14, Cluj-Napoca, Transylvania 3 / 24 January 26th, 2013
to change very quickly project use-cases started to vary maintenance time started to grow (tests, updates & such) development got slower (the bigger the codebase, the noisier it gets) GeekMeet #14, Cluj-Napoca, Transylvania 4 / 24 January 26th, 2013
to change very quickly project use-cases started to vary maintenance time started to grow (tests, updates & such) development got slower (the bigger the codebase, the noisier it gets) GeekMeet #14, Cluj-Napoca, Transylvania 4 / 24 January 26th, 2013
to change very quickly project use-cases started to vary maintenance time started to grow (tests, updates & such) development got slower (the bigger the codebase, the noisier it gets) GeekMeet #14, Cluj-Napoca, Transylvania 4 / 24 January 26th, 2013
to change very quickly project use-cases started to vary maintenance time started to grow (tests, updates & such) development got slower (the bigger the codebase, the noisier it gets) GeekMeet #14, Cluj-Napoca, Transylvania 4 / 24 January 26th, 2013
to change very quickly project use-cases started to vary maintenance time started to grow (tests, updates & such) development got slower (the bigger the codebase, the noisier it gets) GeekMeet #14, Cluj-Napoca, Transylvania 4 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
not your problem, here is why?! if you have plenty of cash (usually you don’t), you can and probably want to optimize if you have no time constraints (usually you do), doing some refactoring can help if you love refactoring (usually you don’t), you will end up rewriting components/tests and delay feature releases look at the code organization because running the test suite for 30 minutes is not fun! because your CI will love fast builds because some developers do not care about pull requests related to assets or views because at some point you will want an API for your app, and some OAuth, and that better be not the same old controller none of the above?! So I am wrong and you should look at your code GeekMeet #14, Cluj-Napoca, Transylvania 5 / 24 January 26th, 2013
cheaper and easier. Sure it needs some know-how, but hey, you were not born programming, you learned that too! GeekMeet #14, Cluj-Napoca, Transylvania 6 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
an engine, which ensures no integration issues: migrations will run fine mount it and leverage from any defined routes inherit any engine resource to customize/change the behaviour all your Rails gems will play nice with engines Bundle it in your Gemfile, it is just another gem in the end engine carries it’s own tests, reduces main app testing time codebase gets smaller, easier to follow / assign across teams cons testing engines might not be so straight engines are not yet first class Rails citizens, get ready to patch things along the way the dummy app issue not very popular, you get better at engines by working with engines GeekMeet #14, Cluj-Napoca, Transylvania 7 / 24 January 26th, 2013
important files that make an engine gem look different from a regular one. gmengine/lib/gmengine.rb 1 require ”gmengine/engine” # if defined?(Rails) # To avoid ‘bundle console‘ errors 2 3 module Gmengine 4 # Add attributes or define methods relevant to your namespace here 5 end gmengine/lib/gmengine/engine.rb 1 module Gmengine 2 class Engine < ::Rails::Engine 3 # This ensures all your routes, controllers and views 4 # will be living inside our engine namespace 5 isolate_namespace Gmengine 6 end 7 end GeekMeet #14, Cluj-Napoca, Transylvania 10 / 24 January 26th, 2013
creating controllers or models for an engine than for a regular Rails app. Generating a model ~$ rails g model post title:string content:text invoke active_record create db/migrate/20130120140937_create_gmengine_posts.rb create app/models/gmengine/post.rb Generating a controller ~$ rails g controller posts new index create app/controllers/gmengine/posts_controller.rb route get ”posts/index” route get ”posts/new” invoke erb create app/views/gmengine/posts create app/views/gmengine/posts/new.html.erb create app/views/gmengine/posts/index.html.erb invoke helper create app/helpers/gmengine/posts_helper.rb invoke rspec create spec/helpers/gmengine/posts_helper_spec.rb invoke assets invoke js create app/assets/javascripts/gmengine/posts.js invoke css create app/assets/stylesheets/gmengine/posts.css GeekMeet #14, Cluj-Napoca, Transylvania 11 / 24 January 26th, 2013
dummy app in order to be tested. There are two options here: generate the app and carry it over in your spec directory write a generator that will bootstrap an app before running tests The first option is not that DRY and (personal opinion) conceptually wrong. Until Rails v4.0 is released, here is an example of such a generator. GeekMeet #14, Cluj-Napoca, Transylvania 12 / 24 January 26th, 2013
dummy app in order to be tested. There are two options here: generate the app and carry it over in your spec directory write a generator that will bootstrap an app before running tests The first option is not that DRY and (personal opinion) conceptually wrong. Until Rails v4.0 is released, here is an example of such a generator. GeekMeet #14, Cluj-Napoca, Transylvania 12 / 24 January 26th, 2013
require ’rails/generators/rails/plugin_new/plugin_new_generator’ 3 4 module Gmengine 5 class DummyGenerator < Rails::Generators::PluginNewGenerator 6 7 def self.default_source_root 8 Rails::Generators::PluginNewGenerator.default_source_root 9 end 10 11 def do_nothing 12 end 13 14 alias :create_root :do_nothing 15 alias :create_root_files :do_nothing 16 alias :create_app_files :do_nothing 17 alias :create_config_files :do_nothing 18 alias :create_lib_files :do_nothing 19 alias :create_public_stylesheets_files :do_nothing 20 alias :create_javascript_files :do_nothing 21 alias :create_script_files :do_nothing 22 alias :update_gemfile :do_nothing 23 alias :create_test_files :do_nothing 24 alias :finish_template :do_nothing 25 26 end 27 end GeekMeet #14, Cluj-Napoca, Transylvania 13 / 24 January 26th, 2013
Here are the steps in order to get things ready: add rspec-rails to your gemspec file customize the task to run our dummy app generator before starting any test (see the next slide) install RSpec: rails generate rspec:install tweak spec/spec helper.rb to load the dummy app for tests 1 # Do not load default generated path, use the dummy app path 2 # require File.expand_path(”../../config/environment”, __FILE__) 3 require File.expand_path(’../dummy/config/environment.rb’, __FILE__) 4 require ’rspec/rails’ 5 require ’rspec/autorun’ GeekMeet #14, Cluj-Napoca, Transylvania 14 / 24 January 26th, 2013
route with your engine name value. gmengine/spec/controllers/gmengine/post controller spec.rb 1 require ’spec_helper’ 2 module Gmengine 3 describe PostsController do 4 describe ”GET ’new’” do 5 it ”returns http success” do 6 get ’new’, :use_route => :gmengine 7 response.should be_success 8 end 9 end 10 describe ”GET ’index’” do 11 it ”returns http success” do 12 get ’index’, :use_route => :gmengine 13 response.should be_success 14 end 15 end 16 end 17 end GeekMeet #14, Cluj-Napoca, Transylvania 16 / 24 January 26th, 2013
need to work with engine router: gmapp/config/routes.rb Gmengine::Engine.routes.draw do get ”posts/new”, :as => ’publish’ get ”posts/index”, :as => ’all’ end Courseware::Application.routes.draw do # Mount the Gmengine routes mount Gmengine::Engine => ’/’ end GeekMeet #14, Cluj-Napoca, Transylvania 19 / 24 January 26th, 2013
to generate factories you can inherit all the fabricators defined in your engine gmapp/spec/support/fabrication.rb Fabrication.configure do |config| config.fabricator_path = [ ’spec/fabricators’, # Load engine fabricators Gmengine::Engine.root.join( ’spec’, ’fabricators’).relative_path_from(Gmengine::Application.root) ] end Fabrication gem configuration page GeekMeet #14, Cluj-Napoca, Transylvania 21 / 24 January 26th, 2013
to deploy engines might be less pleasant you can help it a bit if you are on GitHub: create a new authorization token ~$ curl -u ’USERNAME’ -d ’{”scopes”:[”repo”],”note”:”Key to use at deploys”}’ \ https://api.github.com/authorizations now add it to the gmapp/Gemfile source :rubygems ... gem ’gmengine’, :git => ’https://TOKEN:[email protected]/USER/gmengine.git’ ... doing this basically removes any need of deploy keys / ssh access keys GitHub Authorizations API page GeekMeet #14, Cluj-Napoca, Transylvania 22 / 24 January 26th, 2013
API – edgeapi.rubyonrails.org/classes/Rails/Engine.html Writing a Rails Engine by Erik Michael-Ober – youtube.com/watch?v=Rvxcc46fox0 Rails Engines in real world Forem gem – github.com/radar/forem Spree gem – github.com/spree Travis-CI – github.com/travis-ci These slides – github.com/stas/rails-engines-slides-geekmeet GeekMeet #14, Cluj-Napoca, Transylvania 24 / 24 January 26th, 2013