Upgrade to Pro — share decks privately, control downloads, hide ads and more …

On Rails Engines: How to profit, test and deploy.

On Rails Engines: How to profit, test and deploy.

My slides from GeekMeet #14 meetup in Cluj-Napoca.
http://geekmeet.ro

Get the code on github:
https://github.com/stas/rails-engines-slides-geekmeet

Stas Sușcov

January 26, 2013
Tweet

More Decks by Stas Sușcov

Other Decks in Programming

Transcript

  1. On Rails Engines.
    How to profit, test and deploy.
    Stas Sușcov ([email protected])
    GeekMeet #14, Cluj-Napoca, Transylvania
    January 26th, 2013
    GeekMeet #14, Cluj-Napoca, Transylvania 1 / 24 January 26th, 2013

    View Slide

  2. About Stas
    a nerd
    picky developer
    interests: web/operations
    on Ruby since 2011
    (Œ(food wine cycling))
    GeekMeet #14, Cluj-Napoca, Transylvania 2 / 24 January 26th, 2013

    View Slide

  3. We started Coursewa.re in 2012,
    which is a SaaS social learning
    environment.
    Lots of experience I am sharing today comes from building this platform.
    GeekMeet #14, Cluj-Napoca, Transylvania 3 / 24 January 26th, 2013

    View Slide

  4. The story
    started as a Rails project
    business requirements started 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

    View Slide

  5. The story
    started as a Rails project
    business requirements started 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

    View Slide

  6. The story
    started as a Rails project
    business requirements started 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

    View Slide

  7. The story
    started as a Rails project
    business requirements started 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

    View Slide

  8. The story
    started as a Rails project
    business requirements started 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

    View Slide

  9. Identify the issue
    stop looking at your code, that is 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

    View Slide

  10. Identify the issue
    stop looking at your code, that is 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

    View Slide

  11. Identify the issue
    stop looking at your code, that is 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

    View Slide

  12. Identify the issue
    stop looking at your code, that is 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

    View Slide

  13. Identify the issue
    stop looking at your code, that is 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

    View Slide

  14. Identify the issue
    stop looking at your code, that is 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

    View Slide

  15. Identify the issue
    stop looking at your code, that is 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

    View Slide

  16. Identify the issue
    stop looking at your code, that is 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

    View Slide

  17. Identify the issue
    stop looking at your code, that is 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

    View Slide

  18. Identify the issue
    stop looking at your code, that is 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

    View Slide

  19. My point is that building a
    modular/components-based codebase
    is faster, 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

    View Slide

  20. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  21. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  22. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  23. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  24. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  25. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  26. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  27. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  28. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  29. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  30. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  31. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  32. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  33. Looking at Rails Engines
    pros
    every Rails app is basically 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

    View Slide

  34. Overall: you will love it, unless your
    app complexity/functionality is not
    the subject.
    GeekMeet #14, Cluj-Napoca, Transylvania 8 / 24 January 26th, 2013

    View Slide

  35. Creating an engine
    There are two types of engines:
    Left: mountable, engine close to a full app, has routes, controllers, views and assets
    Right: simple, close to a generic gem structure; ideal to build Rails specific gems (generators, assets, etc. . . )
    Tip: avoid characters like - or in engine names.
    ~$ rails plugin new gmengine --skip-test-unit --mountable
    create README.rdoc
    create Rakefile
    create gmengine.gemspec
    create MIT-LICENSE
    create Gemfile
    create app
    create app/controllers/gmengine/application_controller.rb
    create app/helpers/gmengine/application_helper.rb
    create app/views/layouts/gmengine/application.html.erb
    create app/assets/images/gmengine
    create config/routes.rb
    create lib/gmengine.rb
    create lib/tasks/gmengine_tasks.rake
    create lib/gmengine/version.rb
    create lib/gmengine/engine.rb
    create app/assets/stylesheets/gmengine/application.css
    create app/assets/javascripts/gmengine/application.js
    create script
    create script/rails
    run bundle install
    ~$ rails plugin new gmengine --skip-test-unit
    create README.rdoc
    create Rakefile
    create gmengine.gemspec
    create MIT-LICENSE
    create Gemfile
    create lib/gmengine.rb
    create lib/tasks/gmengine_tasks.rake
    create lib/gmengine/version.rb
    run bundle install
    GeekMeet #14, Cluj-Napoca, Transylvania 9 / 24 January 26th, 2013

    View Slide

  36. A closer look at the mountable engine
    There are two 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

    View Slide

  37. Working with an engine
    There is not much difference from 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

    View Slide

  38. Testing a Rails engine
    A Rails engine requires a separate 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

    View Slide

  39. Testing a Rails engine
    A Rails engine requires a separate 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

    View Slide

  40. Rails dummy app generator
    gmengine/lib/gmengine/generators/dummy generator.rb
    1 require ’rails/generators’
    2 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

    View Slide

  41. Preparing the engine for testing
    We will be using RSpec. 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

    View Slide

  42. gmengine/Rakefile
    1 Bundler::GemHelper.install_tasks
    2
    3 require ’rspec/core/rake_task’
    4 RSpec::Core::RakeTask.new(:spec => :dummy_app) do |t|
    5 t.pattern = File.expand_path(’../spec/**/*_spec.rb’, __FILE__)
    6 end
    7 task :default => :spec
    8
    9 desc ’Generates a dummy app for testing’
    10 task :dummy_app => [:setup, :install_migrations, :migrate]
    11
    12 task :setup do
    13 require ’rails’
    14 require ’gmengine’
    15 require ’gmengine/generators/dummy_generator’
    16
    17 dummy = File.expand_path(’../spec/dummy’, __FILE__)
    18 sh ”rm -rf #{dummy}”
    19 Gmengine::DummyGenerator.start(
    20 %W(. --quiet --force --skip-bundle --old-style-hash --dummy-path=#{dummy})
    21 )
    22 end
    23
    24 task :install_migrations do
    25 rakefile = File.expand_path(’../spec/dummy/Rakefile’, __FILE__)
    26 sh(”rake -f #{rakefile} gmengine:install:migrations”)
    27 end
    28
    29 task :migrate do
    30 rakefile = File.expand_path(’../spec/dummy/Rakefile’, __FILE__)
    31 sh(”rake -f #{rakefile} db:create db:migrate db:test:prepare”)
    32 end
    GeekMeet #14, Cluj-Napoca, Transylvania 15 / 24 January 26th, 2013

    View Slide

  43. Testing routes / controllers
    Make sure you always pass :use 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

    View Slide

  44. Using a Rails engine
    Engines are pretty much gems, just update your Gemfile to start
    using it.
    gmapp/Gemfile
    source :rubygems
    ...
    gem ’gmengine’, :path => ’../gmengine’
    ...
    GeekMeet #14, Cluj-Napoca, Transylvania 17 / 24 January 26th, 2013

    View Slide

  45. Some tips.
    GeekMeet #14, Cluj-Napoca, Transylvania 18 / 24 January 26th, 2013

    View Slide

  46. Re-defining routes
    In order to customize engine routes, you will 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

    View Slide

  47. Reusable fixtures
    in order to reuse available fixtures, make sure you update
    RSpec fixtures path
    gmapp/spec/support/fixtures.rb
    RSpec.configure do |config|
    config.fixture_path = ::Gmengine::Engine.root.join(’spec’, ’fixtures’)
    end
    GeekMeet #14, Cluj-Napoca, Transylvania 20 / 24 January 26th, 2013

    View Slide

  48. Reusable factories with Fabrication
    if you are using Fabrication gem 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

    View Slide

  49. Deploying using GitHub OAuth tokens
    provisioning an infrastructure in order 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

    View Slide

  50. Questions please. . .
    Thank you for your time.
    GeekMeet #14, Cluj-Napoca, Transylvania 23 / 24 January 26th, 2013

    View Slide

  51. Online resources worth checking
    Rails Engine Docs
    Guide – guides.rubyonrails.org/engines.html
    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

    View Slide