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

Refactoring towards Component-based Rails Architectures @ RailsConf 2014

shagemann
April 23, 2014

Refactoring towards Component-based Rails Architectures @ RailsConf 2014

You have a big Rails app and are feeling the pains? Stories are hard to deliver, code is hard to refactor, and your tests take a looong time? Getting you and your codebase out of this situation requires you to stop developing a "Rails application” and start refactoring towards your domain. I will discuss how and where you refactor towards a more structured and manageable application, a component-based Rails architecture.

shagemann

April 23, 2014
Tweet

More Decks by shagemann

Other Decks in Technology

Transcript

  1. Big Rails

    View Slide

  2. https://github.com/josh-jacobson/Wedloom

    View Slide

  3. Refactoring towards Component-
    based Rails Architectures
    Stephan Hagemann
    !
    Pivotal Labs
    Boulder, CO

    View Slide

  4. Component-based Rails architectures

    View Slide

  5. #cbra

    View Slide

  6. View Slide

  7. View Slide

  8. github.com/shageman/the_next_big_thing

    View Slide

  9. Teaser
    Email
    Signup
    Annoyance
    Event
    Counter
    Rails Container

    View Slide

  10. Proxy
    Partner API
    Rails Container
    Registration
    Internal API

    View Slide

  11. Availability and
    Booking
    Rails Travel Site
    Payment
    Gateway
    Conversion
    Tracking

    View Slide

  12. Rails TV Shows with Social Network
    Global Admin Show Admin
    SMS Interface
    Social Network
    Publisher
    Admin UI
    Users and
    Channels

    View Slide

  13. View Slide

  14. WAT?

    View Slide

  15. Because it helps

    View Slide

  16. How to write #cbra?
    github.com/shageman/the_next_big_thing
    !
    http://pivotallabs.com/tag/rails-application-suites/
    !
    confreaks.com/presenters/790-stephan-hagemann
    confreaks.com/presenters/784-ben-smith
    !
    https://leanpub.com/cbra

    View Slide

  17. Big Rails

    View Slide

  18. View Slide

  19. How Big?
    find . -iname "*.rb" -type f -exec cat {} \; | wc -l

    View Slide

  20. How Big?
    gist.github.com/shageman/11185993

    View Slide

  21. View Slide

  22. View Slide

  23. Growing size

    View Slide

  24. View Slide

  25. View Slide

  26. Exploding complexity
    Size
    Possible
    Interactions

    View Slide

  27. Versions of Large
    VS

    View Slide

  28. View Slide

  29. View Slide

  30. Size
    Possible
    Interactions
    Reduced (Exploding) complexity

    View Slide

  31. View Slide

  32. the rich get richer and the poor get

    View Slide

  33. - “Ain't We Got Fun?” - Gus Kahn, Raymond B. Egan
    the rich get richer and the poor get—children!

    View Slide

  34. Preferential Attachment

    View Slide

  35. Entities (sorted by size)
    Size

    View Slide

  36. Big Open-Source Rails Apps
    browsercms!
    calagator!
    canvas-lms!
    citizenry!
    diaspora
    opencongress!
    opengovernment!
    portlandcrime!
    railscollab!
    rubygems.org
    locomotivecms!
    fat_free_crm!
    fulcrum!
    loc_counts!
    onebody
    skyline!
    snorby!
    spot-us!
    spree!
    teambox
    tracks

    View Slide

  37. What About Code?
    find . -iname "*.rb" -type f -exec wc -l {} \; | sort -rn

    View Slide

  38. What About Code?
    https://gist.github.com/shageman/11190909

    View Slide

  39. View Slide

  40. View Slide

  41. user.rb

    View Slide

  42. View Slide

  43. ActiveRecord Associations

    View Slide

  44. has_many

    View Slide

  45. users model

    View Slide

  46. id name home
    1 Kate Chicago
    2 Pete Boulder
    3 Ian Boulder
    4 Sam Chicago
    users table
    users model

    View Slide

  47. id name code
    1 red #FF0000
    2 green #00FF00
    3 blue #0000FF
    4 yellow #FFFF00
    colors table
    colors model

    View Slide

  48. How many has many?
    ack " has_many " -c | awk -F ":" '{print $2,$1}' | grep -v "0" | sort -rn

    View Slide

  49. How many has many?
    https://gist.github.com/shageman/11191030

    View Slide

  50. View Slide

  51. View Slide

  52. user.rb

    View Slide

  53. View Slide

  54. View Slide

  55. View Slide

  56. we can do better

    View Slide

  57. View Slide

  58. View Slide

  59. View Slide

  60. View Slide

  61. SOLID

    View Slide

  62. Single Responsibility Principle

    View Slide

  63. Things that don’t belong

    View Slide

  64. SRP - where?
    Method
    Class
    Module
    Yes!
    Yes!

    View Slide

  65. SRP - where?
    Method
    Class
    Namespace
    Yes!
    Yes!

    View Slide

  66. Mixins

    View Slide

  67. SRP - where?
    Method
    Class
    Namespace
    Component
    Application
    Now you can!
    Yes!
    Yes!
    You should! … Anyone?
    You should!

    View Slide

  68. Components over SOAs
    1 repo
    1 test suite (and splittable!)
    1 deployment
    no additional versioning constraints
    easier refactorings between parts

    View Slide

  69. Within a SOA componentize your apps

    View Slide

  70. Refactoring towards #cbra

    View Slide

  71. View Slide

  72. Teasing out App Component
    Extracting Functional Component

    View Slide

  73. https://leanpub.com/cbra

    View Slide

  74. Teasing out App Component

    View Slide

  75. Teasing out App Component
    0. Got tests?

    View Slide

  76. Teasing out App Component
    1. Find a vertical that makes sense on its own
    V
    C
    M

    View Slide

  77. Teasing out App Component
    2. Namespace controllers, views, and models
    V
    C
    M

    View Slide

  78. Teasing out App Component
    2. Namespace controllers, views, and models
    V
    C
    M

    View Slide

  79. Teasing out App Component
    3. Hunt down other dependencies
    V
    C
    M

    View Slide

  80. Teasing out App Component
    4. Move all namespaced code into an engine
    V
    C
    M

    View Slide

  81. Teasing out App Component
    4b. rails plugin new MY_NEW_COMPONENT --full --mountable
    V
    C
    M

    View Slide

  82. Teasing out App Component
    Step 3. PROFIT!
    V
    C
    M

    View Slide

  83. Teasing out App Component
    PROTIP: Special Case
    V
    C
    M
    M

    View Slide

  84. Extracting Functional Component

    View Slide

  85. Extracting Functional Component
    0. Got tests?

    View Slide

  86. Extracting Functional Component
    1. Find functional component

    View Slide

  87. Extracting Functional Component
    2. bundle gem MY_NEW_COMPONENT

    View Slide

  88. Extracting Functional Component
    3. move all files into gem (and namespace)

    View Slide

  89. Extracting Functional Component
    4. move the other stuff the gem needs

    View Slide

  90. Extracting Functional Component
    5. Require the gem from your app

    View Slide

  91. Extracting Functional Component
    6. Add shims/ports/adapters to make the app happy

    View Slide

  92. Extracting Functional Component
    Step 3. PROFIT!

    View Slide

  93. View Slide

  94. I will help
    @shageman

    View Slide

  95. View Slide

  96. View Slide

  97. Thanks!
    @shageman

    View Slide