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

Jumping Rails 3.2 => 6.beta in 1 Person Month

Jumping Rails 3.2 => 6.beta in 1 Person Month

華麗的一躍:Rails 3.2 升級 Rails 6.beta 經驗分享

女人迷網站在 2019 的農曆春節前,經歷了 Rails 三個版號的大躍進,本次將由工程師小蟹跟大家做升級的經驗分享,包含:
* 工作哲學
* 如何決定升級
* 升級期間遇到的關卡
* deadline、上線規劃
* Rails 6 新功能介紹

Jerry Lee

April 09, 2019
Tweet

More Decks by Jerry Lee

Other Decks in Technology

Transcript

  1. Jumping Rails 3.2 => 6.beta in 1 Person Month 華麗的一躍:Rails

    3.2 升級 Rails 6.beta 經驗分享 講者:小蟹
  2. 小蟹@wildjcrt • Web Pioneer @ 女人迷 womany.net ◦ Use Ruby/Rails

    since 2010 • OSS community ◦ Rails Taiwan co-founder ◦ g0v contributor ▪ ’Amis moedict maintainer 2
  3. Part 1: Context 3 => 6, why!? 1. Womany architecture

    2. Philosophy 3. To upgrade or not to upgrade 4
  4. 5

  5. 7

  6. 8

  7. 11

  8. • When you join a conference… ◦ junior: entry/intro talk

    ◦ intermediate: feature/pattern/opt talk ◦ senior: mindset talk • credit to xdite 13
  9. • Prevent to use gem if possible ◦ Write our

    own libs ◦ Extract usful code by gems • Find root cause ◦ Trace source code / issues / PRs • credit to godfat Our practices 15
  10. • Chinese translating gem in order to know Rack and

    middleware ◦ https://github.com/womany/chinese_t2s ◦ https://guides.rubyonrails.org/rails_on_rack.html ◦ https://rack.github.io/ Ex: our own lib 16
  11. Ex: extract usful code • Hash#transform_keys ◦ Monkey patch in

    config/initializers ◦ https://github.com/rails/rails/blob/v5.2.3/activesupport/li b/active_support/core_ext/hash/keys.rb#L4-L31 • Decrypt session cookie to get user_id ◦ https://gist.github.com/wildjcrt/6359713fa770d2779270 51fdeb30ebbf 17
  12. To upgrade or not to upgrade • That is a

    question. ◦ Why keep Rails 3.2 for 6 years? ▪ Stable ▪ Familiar code 18
  13. Why upgrade? • dependencies ◦ gems ◦ front-end tools •

    security issues • scalability • case: The Past, Present and Future of Rails at GitHub 19
  14. • Highly control our own code base ◦ Content +

    EC • Clear architecture to prevent upgrade all at once • No big changes between 5.2 and 6.0 ◦ check all release notes for version > 3.2 ◦ check all issues in milestone 6.0 Why dare womany upgrade? 20
  15. • 2018/12 ~ 2019/02/01 (before Taiwan Lunar New Year) •

    Daily work changes: ◦ 1. Upgrade to rails 6.beta ◦ 2. Lead a intern ◦ 3. Fix urgent issues ◦ delegate all others Proposal and plan 21
  16. 1. Rails/Ruby 2. Upgrading codes 3. Webpacker 4. Strong params

    5. ckeditor gem 6. deploy recipes Part 2: Upgrade > 100 commits 22
  17. Before v.s. After • Ruby 2.3.5 • Rails 3-2-stable •

    Sprocket • Unicorn • Ruby 2.6+ • Rails 6.0 beta3 • Webpacker • Puma • Test 23
  18. 1. Rails/Ruby version • Ruby 2.3.5 => 2.6+ ◦ lucky

    for us, it’s basically compatible. • How to start a new project with rails master? ◦ https://stackoverflow.com/a/52467794 24
  19. $ mkdir example $ cd example $ echo "source 'https://rubygems.org'"

    >> Gemfile $ echo "gem 'rails', git: 'https://github.com/rails/rails.git'" >> Gemfile $ bundle install $ bundle exec rails new womany -d mysql 25
  20. • Make a new project for trial. • Copy all

    models • Run `Model.count` for all models • Fix code until all pass ◦ scopes, relationships, validates, callbacks • Check point: run each `Model.count` without error Simple case to verify 26
  21. • Create branch to do upgrade • Setup Gemfile •

    Check new files and config/ line by line ◦ new config: add or skip ◦ existed config: keep, delete, or adjust • New features setup with Rails 6 2. Upgrade and fix codes 27
  22. • ApplicationMailer • ApplicationRecord • config/ ◦ boot.rb and environments

    ◦ config/routes.rb ◦ remove monkey patches • gem dependencies • Checkout point: `bin/rails c` without error Upgrading details 28
  23. • Move js/css/images • Use yarn to add js/css libraries

    • Fix css require and image-url • Fix js require, import and export • Use resolve path • Source Map config • Remove Sprocket and use webpacker methods • Checkout point: `bin/rails s` and open browser 3. Webpacker 29
  24. require "rails" require "active_model/railtie" # require "active_job/railtie" require "active_record/railtie" #

    require "active_storage/engine" require "action_controller/railtie" require "action_mailer/railtie" # require "action_mailbox/engine" require "action_view/railtie" # require "action_cable/engine" # require "rails/test_unit/railtie" # require "sprockets/railtie" 30
  25. • credit to our intern Lisbeth • Use `binding.pry` to

    check fields and setup • Some issues ◦ ugly code for nested fields ◦ Don’t support array in first level • Checkout point: `bin/rails s` and try form submit 4. Strong parameters 31
  26. • Hard work on it for a week ◦ Need

    to upload image with carrierwave ◦ Need to keep ckeditor at 4.5.x ◦ Need all existed plugins to work well ◦ Need to work with Webpacker but not Sprocket • Separate ckeditor version and gem version ◦ gem version: v4.3.0 ◦ config.cdn_url: 4.5.11 • Checkout point: `bin/rails s` on Admin 5. ckeditor gem 32
  27. • Still capistrano 2.15.x • Write new deploy recipes: ◦

    puma ◦ webpacker • Checkout point: `cap deploy` 6. deploy recipes 33
  28. • lock deadline because of Lunch New Year • Launch

    without testing • Use error handling service Sentry to fix ASAP • 2 steps to launch ◦ Main and API ◦ Admin Before launch 35
  29. • Launch main site • API is needed to launch

    at the same time ◦ Parsing session for user_id • Hack login in Admin ◦ Encrypt user_id with AES in cookie • Fix bugs for a week First Launch 36
  30. • ~90 commits • 2,389 files changed • 73,313 insertions(+)

    • 66,566 deletions(-) Git log in first launch 37
  31. • Upgrading ckeditor gem • Strong parameters in Admin •

    Launch admin • Fix bugs 2 days and then 9 days Lunar New Year • Maintenances/Optimize until now Second launch 38
  32. OMT: Rails 6 New features 1. Security 2. Multi-DB 3.

    Zeitwerk 4. Parallel testing 5. Action Text and Action Mailbox 6. Others 39
  33. • signed/encrypted cookies • CSP (Content Security Policy) • hosts

    • per-environment credentials 1. Security 40
  34. • Separate read and write databases • 8+ PRs for

    this feature ◦ https://github.com/rails/rails/pulls?q=is%3Apr+is%3Acl osed+label%3Aactiverecord+author%3Aeileencodes+ milestone%3A6.0.0 ◦ Checkout Part 1~8 2. Multi-DB 41
  35. development: base: primary: database: base_writing_db user: root replica: database: base_reading_db

    user: ro_user animals: primary: database: animals_writing_db user: root replica_one: database: animals_reading_db user: ro_user replica_two: database: animals_reading_db user: ro_user class ApplicationRecord < AR::Base connects_to database: { writing: :base_primary, reading: :base_replica } end class Animal < ApplicationRecord # Built-in round robin for reading connects_to database: { writing: :animals_primary, reading: :animals_replica_one, reading_slow: :animals_replica_two } end 42
  36. • Parallel testing • Action Text • Action Mailbox •

    Action Cable with ES6 • Action Cable Testing • Rails Conductor … more big changes 44
  37. • Ruby 2.5.0+ • New command to change databases •

    Scalable by default • Webpacker by default • Endless ranges in where conditions Others 45
  38. • cache_key_with_version 5.2+ ◦ #cache_key will be `model/id` but not

    `model/id-timestamp` • redirect external_host, allow_other_host: true 5.2+ ◦ fail with 500 code • params#to_unsafe_h 5.0+ • class name by zeitwerk 6.0+ ◦ API => Api Be careful 46
  39. • puma-dev with local https ◦ create domain file with

    port number • Run `bin/rails s` ◦ use param `-p PORT` ◦ use param `-P PID` to run multiple rails server ◦ easy to use `binding.pry` for debugging Pro tips 47