Keeping Your Massive Rails App From Turning Into a S#!t Show (WindyCityRails 2013)

6d48d3849102b57bbc1462c0da0b3866?s=47 Benjamin Smith
September 12, 2013

Keeping Your Massive Rails App From Turning Into a S#!t Show (WindyCityRails 2013)

6d48d3849102b57bbc1462c0da0b3866?s=128

Benjamin Smith

September 12, 2013
Tweet

Transcript

  1. Keeping Your Massive Rails App From Turning Into a S#!t

    Show Thursday, September 12, 13
  2. Keeping Your Massive Rails App From Turning Into a SNAKE

    Show Thursday, September 12, 13
  3. Keeping Your Massive Rails App From Turning Into a SNAKE

    Show Thursday, September 12, 13
  4. Keeping Your Massive Rails App From Turning Into a CYLON

    Show Thursday, September 12, 13
  5. Keeping Your Massive Rails App From Turning Into a SHEEP

    Show Thursday, September 12, 13
  6. gem “sheep” gem “sheepsafe” gem “sheep-sebastian” gem “SheepDog” Thursday, September

    12, 13
  7. gem “sheep” gem “sheepsafe” gem “sheep-sebastian” gem “SheepDog” Thursday, September

    12, 13
  8. Thursday, September 12, 13

  9. Thursday, September 12, 13

  10. Keeping Your Massive Rails App From Turning Into a S#!t

    Show Benjamin Smith Thursday, September 12, 13
  11. Keeping Your Massive Rails App From Turning Into a S#!t

    Show Benjamin Smith Thursday, September 12, 13
  12. Keeping Your Massive Rails App From Turning Into a S#!t

    Show Benjamin Smith Thursday, September 12, 13
  13. Keeping Your Massive Rails App From Turning Into a S#!t

    Show Benjamin Smith @benjamin_smith Thursday, September 12, 13
  14. Keeping Your Massive Rails App From Turning Into a S#!t

    Show By Architecting It For Success Benjamin Smith Success @benjamin_smith Thursday, September 12, 13
  15. Benjamin Smith Success @benjamin_smith Thursday, September 12, 13

  16. Benjamin Smith Success @benjamin_smith Thursday, September 12, 13

  17. Benjamin Smith Success Architecting Rails @benjamin_smith Thursday, September 12, 13

  18. M @benjamin_smith Thursday, September 12, 13

  19. M V @benjamin_smith Thursday, September 12, 13

  20. M C V @benjamin_smith Thursday, September 12, 13

  21. once upon a time @benjamin_smith Thursday, September 12, 13

  22. success Thursday, September 12, 13

  23. long project Thursday, September 12, 13

  24. big dev team Thursday, September 12, 13

  25. lots of codez Thursday, September 12, 13

  26. scalable Thursday, September 12, 13

  27. big bang release Thursday, September 12, 13

  28. success • long project • big dev team • lots

    of code • scalable • big 1st release @benjamin_smith Thursday, September 12, 13
  29. a grain of salt @benjamin_smith Thursday, September 12, 13

  30. a grain of salt @benjamin_smith Thursday, September 12, 13

  31. success • long project • big dev team • lots

    of code • scalable • big 1st release @benjamin_smith Thursday, September 12, 13
  32. engines Thursday, September 12, 13

  33. a little background @benjamin_smith Thursday, September 12, 13

  34. the product • Multimedia content publishing • A social network

    • iOS app for consumers (using JSON API) • CMS (Rails) for admins @benjamin_smith Thursday, September 12, 13
  35. started simple @benjamin_smith Thursday, September 12, 13

  36. Thursday, September 12, 13

  37. Thursday, September 12, 13

  38. Thursday, September 12, 13

  39. Thursday, September 12, 13

  40. Thursday, September 12, 13

  41. Thursday, September 12, 13

  42. Thursday, September 12, 13

  43. Thursday, September 12, 13

  44. Thursday, September 12, 13

  45. not too bad Thursday, September 12, 13

  46. Thursday, September 12, 13

  47. Thursday, September 12, 13

  48. Thursday, September 12, 13

  49. Thursday, September 12, 13

  50. Thursday, September 12, 13

  51. Thursday, September 12, 13

  52. Thursday, September 12, 13

  53. Thursday, September 12, 13

  54. Thursday, September 12, 13

  55. but why stop there? @benjamin_smith Thursday, September 12, 13

  56. Thursday, September 12, 13

  57. Thursday, September 12, 13

  58. Thursday, September 12, 13

  59. Thursday, September 12, 13

  60. Thursday, September 12, 13

  61. Thursday, September 12, 13

  62. Thursday, September 12, 13

  63. how to get started Thursday, September 12, 13

  64. rails plugin new engine_name --mountable @benjamin_smith Thursday, September 12, 13

  65. gem "engine_name", path: "path/to/engine_name" @benjamin_smith Thursday, September 12, 13

  66. mount EngineName::Engine => "/engine_name", :as => "engine_name" @benjamin_smith Thursday, September

    12, 13
  67. rails plugin new engine_name --mountable @benjamin_smith Thursday, September 12, 13

  68. rails plugin new engine_template --mountable @benjamin_smith Thursday, September 12, 13

  69. s/engine_template/new_engine_name/g s/EngineTemplate/NewEngineName/g for file in $(find . -name "*engine_template*") do

    mv $file `echo $file | sed s/engine_template/$1/` done @benjamin_smith Thursday, September 12, 13
  70. bundle gem gem_name @benjamin_smith Thursday, September 12, 13

  71. gem "gem_name", path: "path/to/gem_name" @benjamin_smith Thursday, September 12, 13

  72. bundle gem gem_template s/gem_template/new_gem_name/g s/GemTemplate/NewGemName/g for file in $(find .

    -name "*gem_template*") do mv $file `echo $file | sed s/gem_template/$1/` done @benjamin_smith Thursday, September 12, 13
  73. got it? got it? Thursday, September 12, 13

  74. engines the right way Thursday, September 12, 13

  75. fully contained engines • all tables namespaced • migrations •

    tests @benjamin_smith Thursday, September 12, 13
  76. table namespacing @benjamin_smith Thursday, September 12, 13

  77. Thursday, September 12, 13

  78. Thursday, September 12, 13

  79. Thursday, September 12, 13

  80. Thursday, September 12, 13

  81. Thursday, September 12, 13

  82. migrations inside engines @benjamin_smith Thursday, September 12, 13

  83. rake your_engine_name:install:migrations @benjamin_smith Thursday, September 12, 13

  84. module EngineWithMigrations class Engine < ::Rails::Engine isolate_namespace EngineWithMigrations initializer :append_migrations

    do |app| unless app.root.to_s.match root.to_s app.config.paths["db/migrate"] += config.paths["db/migrate"].expanded end end end end http://pivotallabs.com/leave-your-migrations-in-your-rails- engines/ Thursday, September 12, 13
  85. one table per migration http://pivotallabs.com/moving-db-tables-between-rails- engines/ Thursday, September 12, 13

  86. testing the engines in isolation @benjamin_smith Thursday, September 12, 13

  87. Thursday, September 12, 13

  88. engines the right way Thursday, September 12, 13

  89. fully contained engines • all tables namespaced • migrations •

    tests @benjamin_smith Thursday, September 12, 13
  90. no circular dependencies @benjamin_smith Thursday, September 12, 13

  91. Thursday, September 12, 13

  92. Thursday, September 12, 13

  93. Thursday, September 12, 13

  94. class User < ActiveRecord::Base has_many :posts end class Post <

    ActiveRecord::Base belongs_to :user end Thursday, September 12, 13
  95. Thursday, September 12, 13

  96. domain api Thursday, September 12, 13

  97. domain api • simple classes to wrap ActiveRecord calls •

    take as input: params or ids • output PORO @benjamin_smith Thursday, September 12, 13
  98. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end private class UserRecord <

    ActiveRecord::Base validates :email, presence: true end end Thursday, September 12, 13
  99. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end private class UserRecord <

    ActiveRecord::Base validates :email, presence: true end end Thursday, September 12, 13
  100. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end private class UserRecord <

    ActiveRecord::Base validates :email, presence: true end end Thursday, September 12, 13
  101. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end private class UserRecord <

    ActiveRecord::Base validates :email, presence: true end end class User def initialize(user_record) self.email = user_record.email end end Thursday, September 12, 13
  102. that’s a lie @benjamin_smith Thursday, September 12, 13

  103. it’s called the Data Mapper pattern @benjamin_smith Thursday, September 12,

    13
  104. Thursday, September 12, 13

  105. @user.posts @post.user Thursday, September 12, 13

  106. class PostManager def find_all_by_user_id(user_id) PostRecord.where(user_id: user_id) # ... convert to

    PORO ... end end Thursday, September 12, 13
  107. class PostManager def find_all_by_user_id(user_id) PostRecord.where(user_id: user_id) # ... convert to

    PORO ... end end post_manager = PostManager.new @posts = post_manager.find_all_by_user_id(@user.id) Thursday, September 12, 13
  108. Thursday, September 12, 13

  109. Thursday, September 12, 13

  110. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end end Thursday, September 12,

    13
  111. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end end user_manager = UserManager.new

    author = user_manager.find_by_id(@post.user_id) Thursday, September 12, 13
  112. Thursday, September 12, 13

  113. Thursday, September 12, 13

  114. engines the right way Thursday, September 12, 13

  115. no circular dependencies @benjamin_smith Thursday, September 12, 13

  116. started simple Thursday, September 12, 13

  117. Thursday, September 12, 13

  118. I live my life one green build at a time

    Thursday, September 12, 13
  119. Thursday, September 12, 13

  120. Thursday, September 12, 13

  121. Thursday, September 12, 13

  122. git whatchanged origin/master.. @benjamin_smith Thursday, September 12, 13

  123. Thursday, September 12, 13

  124. how did it work out? Thursday, September 12, 13

  125. Thursday, September 12, 13

  126. engines are a pain... • LOW velocity for weeks (4-6)

    • client worries • opposite of Rails • one pair to start is a MUST • some technical hurtles • must be diligent about refactoring • monkey patching Rails @benjamin_smith Thursday, September 12, 13
  127. Thursday, September 12, 13

  128. ... but they get better • no slow down in

    development time • they age well • easier parallel development • potential for scaling • smart and fast build scripts @benjamin_smith Thursday, September 12, 13
  129. thumbs up @benjamin_smith Thursday, September 12, 13

  130. Thursday, September 12, 13

  131. class UserManager def find_by_id(id) User.new(UserRecord.find(id)) end private class UserRecord <

    ActiveRecord::Base validates :email, presence: true end end Thursday, September 12, 13
  132. thanks Thursday, September 12, 13

  133. more infoz: @benjamin_smith http://pivotallabs.com/tag/rails-application-suites/ https://github.com/benjaminleesmith/sup_locator Thursday, September 12, 13