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. https://github.com/josh-jacobson/Wedloom

    View full-size slide

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

    View full-size slide

  3. Component-based Rails architectures

    View full-size slide

  4. github.com/shageman/the_next_big_thing

    View full-size slide

  5. Teaser
    Email
    Signup
    Annoyance
    Event
    Counter
    Rails Container

    View full-size slide

  6. Proxy
    Partner API
    Rails Container
    Registration
    Internal API

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. Because it helps

    View full-size slide

  10. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  13. Growing size

    View full-size slide

  14. Exploding complexity
    Size
    Possible
    Interactions

    View full-size slide

  15. Versions of Large
    VS

    View full-size slide

  16. Size
    Possible
    Interactions
    Reduced (Exploding) complexity

    View full-size slide

  17. the rich get richer and the poor get

    View full-size slide

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

    View full-size slide

  19. Preferential Attachment

    View full-size slide

  20. Entities (sorted by size)
    Size

    View full-size slide

  21. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  24. ActiveRecord Associations

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  29. we can do better

    View full-size slide

  30. Single Responsibility Principle

    View full-size slide

  31. Things that don’t belong

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  36. Within a SOA componentize your apps

    View full-size slide

  37. Refactoring towards #cbra

    View full-size slide

  38. Teasing out App Component
    Extracting Functional Component

    View full-size slide

  39. https://leanpub.com/cbra

    View full-size slide

  40. Teasing out App Component

    View full-size slide

  41. Teasing out App Component
    0. Got tests?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. Extracting Functional Component

    View full-size slide

  51. Extracting Functional Component
    0. Got tests?

    View full-size slide

  52. Extracting Functional Component
    1. Find functional component

    View full-size slide

  53. Extracting Functional Component
    2. bundle gem MY_NEW_COMPONENT

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  58. Extracting Functional Component
    Step 3. PROFIT!

    View full-size slide

  59. I will help
    @shageman

    View full-size slide

  60. Thanks!
    @shageman

    View full-size slide