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

Breaking Bad: What Happens When You Defy Conventions?

Breaking Bad: What Happens When You Defy Conventions?

With Rails being over ten years old now, we know that the Rails way works well. It's battle tested and successful. But not all problems we try to solve fit into its idea on how our application should be structured. Come along to find out what happens when you don't want to have an app directory anymore. We will see what is needed in order to fight parts of the Rails convention and if it's worth it.

Recording: http://confreaks.tv/videos/railsconf2017-breaking-bad-what-happens-when-you-defy-conventions

Christoph

April 27, 2017
Tweet

More Decks by Christoph

Other Decks in Programming

Transcript

  1. Breaking Bad 
 What Happens When
 You Defy Conventions? Christoph

    Gockel RailsConf Apr 25 - 27, 2017 Image Originally taken from: https://www.youtube.com/watch?v=TU-PXfzsj4o
  2. ... -M, [--skip-action-mailer], [--no-skip-action-mailer] -O, [--skip-active-record], [--no-skip-active-record] -C, [--skip-action-cable], [--no-skip-action-cable]

    -S, [--skip-sprockets], [--no-skip-sprockets] [--skip-spring], [--no-skip-spring] [--skip-listen], [--no-skip-listen] -J, [--skip-javascript], [--no-skip-javascript] [--skip-turbolinks], [--no-skip-turbolinks] -T, [--skip-test], [—no-skip-test] ...
  3. # config/application.rb require "rails" # Pick the frameworks you want:

    require "active_model/railtie" require "active_job/railtie" require "active_record/railtie" require "action_controller/railtie" require "action_mailer/railtie" require "action_view/railtie" require "sprockets/railtie" # require "rails/test_unit/railtie"
  4. app bin config db lib public spec vendor Gemfile Gemfile.lock

    README.md Rakefile config.ru assets channels controllers helpers jobs mailers models views
  5. lib bin config db lib public spec vendor Gemfile Gemfile.lock

    README.md movies channels controllers helpers jobs mailers models views edit.html.erb index.html.erb movie.rb movie_repository.rb movies_controller.rb show.html.erb application_controller.rb
  6. # config/application.rb config.active_support.bare = true config.cache_classes = true config.enable_dependency_loading =

    false config.eager_load = false config.autoload_once_paths = [] config.autoload_paths = [] config.eager_load_paths = []
  7. ActionController::RoutingError (uninitialized constant Movies::MoviesController): activesupport (4.2.1) lib/active_support/inflector/methods.rb:263:in 'const_get' activesupport (4.2.1)

    lib/active_support/inflector/methods.rb:263:in 'block in constantize' activesupport (4.2.1) lib/active_support/inflector/methods.rb:259:in 'each' activesupport (4.2.1) lib/active_support/inflector/methods.rb:259:in 'inject' activesupport (4.2.1) lib/active_support/inflector/methods.rb:259:in 'constantize' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:70:in 'controller_reference' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:60:in 'controller' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:39:in 'serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:43:in 'block in serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in 'each' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in 'serve'
  8. ActionController::RoutingError (uninitialized constant Movies::MoviesController): activesupport (4.2.1) lib/active_support/inflector/methods.rb:263:in 'const_get' activesupport (4.2.1)

    lib/active_support/inflector/methods.rb:263:in 'block in constantize' activesupport (4.2.1) lib/active_support/inflector/methods.rb:259:in 'each' activesupport (4.2.1) lib/active_support/inflector/methods.rb:259:in 'inject' activesupport (4.2.1) lib/active_support/inflector/methods.rb:259:in 'constantize' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:70:in 'controller_reference' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:60:in 'controller' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:39:in 'serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:43:in 'block in serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in 'each' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in 'serve'
  9. # config/routes.rb Rails.application.routes.draw do ... end module ActiveSupport::Dependencies old_constantize =

    instance_method(:constantize) define_method(:constantize) do |klass| require klass.underscore if klass =~ /Controller/ old_constantize.bind(self).(klass) end end
  10. require "virtus" require "sequel" require "date" require "set" require "uri"

    require "socket" require "securerandom" require "bcrypt" require "thread" require "ostruct" require "yaml" require "json" require "bigdecimal" require "active_support/core_ext/object/blank" require "active_support/core_ext/object/duplicable" require "active_support/core_ext/object/deep_dup" require "active_support/core_ext/object/try"
  11. 0 100 200 300 400 Previous Application New Way Previous

    Application: • 4800 specs • 377 seconds New Way: • 5500 specs • 23 seconds Suite Runtime
  12. 0 5 10 15 20 Previous Application New Way Previous

    Application: • 18 seconds New Way: • 2 seconds Time for One Test
  13. 0 5 10 15 20 require "rails/all" explicit require require

    “rails/all”: • 14 seconds explicit require: • 9 seconds Controller Spec
  14. 0 2 4 6 8 require "rails/all" explicit require require

    “rails/all”: • 6.5 seconds explicit require: • 0.6 seconds Non-Controller Spec
  15. 0 150 300 450 600 Existing Application Projected Optimizations Previous

    Application: • 2600 specs • 510 seconds Projected Optimizations: • 2600 specs • 5-6 minutes Projections
  16. Resources Articles Ruby DeRailed: Fast Tests - https://8thlight.com/blog/myles-megyesi/2013/10/10/ruby-derailed-fast-tests.html Ruby DeRailed:

    Emergent Design - https://8thlight.com/blog/paul-pagel/2013/10/17/ruby-derailed-emergent-design.html The Repository Pattern - https://8thlight.com/blog/mike-ebert/2013/03/23/the-repository-pattern.html Rails is omakase - http://david.heinemeierhansson.com/2012/rails-is-omakase.html Linearity of Bundler and require - https://github.com/rubygems/rubygems/issues/1076 Clean Architecture - https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html Hexagonal Architecture - http://alistair.cockburn.us/Hexagonal+architecture Service Layer - https://martinfowler.com/eaaCatalog/serviceLayer.html Talks RailsConf 2015 - Opening Keynote, David Heinemeier Hansson - https://www.youtube.com/watch?v=KJVTM7mE1Cc Boundaries, Gary Bernhardt - https://www.destroyallsoftware.com/talks/boundaries Ruby Derailed, Myles Megyesi - https://vimeo.com/84696817 Images (if not credited otherwise) https://raumrot.com, https://unsplash.com, https://pexels.com