ONE DOES NOT SIMPLY
UPGRADE TO RAILS 3
Adventures in Upgrading
From Rails 2 to 3
Chris McCann
@testflyjets
github.com/testflyjets
The Task
Upgrade a Rails 2.3.5 app to Rails 3.1
Ultimately upgrade to Rails 4
Why?
Benefits to Upgrading
Security patches
Ruby 2.0
New gems and capabilities, Bundler
Asset pipeline + Sass
Framework improvem...
The App
First app I ever built
Started in 2007
Rails 1.2 initially
Upgraded to 2.3.5
2nd Edition
The App
!
Monkey-patched gems
(mysql, geokit, DJ)
Lots of plugins
Prototype helpers...lots
The App
CSS mess
Homebrewed
authentication
The App
163 models
167 controllers
> 1,000 view templates
12,500 users
Over $500,000 in non-
profit transactions
Testing to the rescue!
Not so much
Resources for Upgrading
Episodes 225, 226, 227
My Hybrid Approach*
Create a new Rails 3 app
Install Rails 3 versions of gems, replace plugins
Get the framework running w...
MySQL
Originally MySQL 5.1 + mysql gem + monkey patch
Not compatible with Rails 3 >> MySQL 5.5 + mysql2
Broke original app...
Plugin > gem conversion
Generally not too terrible
Most plugins available as Rails 3 gems
Can still use vendor/plugins if ...
Framework configuration
Custom configuration code moved from
environment.rb to application.rb
Initializers used extensively ...
UDT: Upgrade Driven Testing
Tests as sanity checks
Try to rapidly touch every model to trigger failures
Tools of choice: rspec, factory_girl, spork, f...
“Canary in a coal mine” tests
I didn’t find a quick way to check my models
Specs you don’t write are all “pending”
Hidden l...
Model changes everywhere
named_scope became scope plus syntax changes
(deprecation)
validates_* to validates (*attributes)...
ActionMailer failer
ActionMailer methods
Mailer methods changed:
create_* and deliver_* are gone
email = Mailer.confirm(user)
email.deliver!
@...
ActionMailer views
Mailer views renamed:
*.text.html.erb to *.html.erb
*.plain.text.erb to *.text.erb!
*.rhtml is complete...
Routing changes
Joys of RESTful routing
Original app had mix of RESTful and controller/action
Bad, bad, bad: Catch-all route
map.connect ‘...
Routing syntax tedium
	
  	
  	
  	
  	
  
flight.resource	
  :roster_import,	
  :controller	
  =>	
  :import,	
  	
  
	
 ...
Controller Testing
Hoped for a straightforward way to sanity check
request specs vs controller specs?
rspec let() vs @var ...
Asset Pipeline
Asset Pipeline partially implemented already
Managed to double-include some files
Watch out for relative pat...
View booby traps
Views can be a pain to test
Over 1,000 view templates in the app
ERB changes to look for:
<% form_for ......
No more Prototype helpers
Prototype helpers removed
remote_form_for!
form_remote_tag!
link_to_remote!
remote_function!
Ajax form/links now done with...
Prototype callbacks
link_to_remote(dues.email_link, !
:url => send_notices_flight_dues_path(@flight, dues),!
:before => "E...
Use jQuery for callbacks
application.js!
!
$("*[data-spinner]")!
.on("ajax:before", function(){ !
$($(this).data('spinner'...
Geocoding and GMap
Used geokit, monkey-patched for exception handling
during auto-geocoding
Google killed GMaps v2 last fa...
tl;dr
Upgrading between major versions is hard
Not having tests makes it MUCH harder
Incremental upgrade is way easier
For...
ONE DOES NOT SIMPLY
UPGRADE TO RAILS 3
Adventures in Upgrading
From Rails 2 to 3
Chris McCann
@testflyjets
github.com/testflyjets
One does not simply "Upgrade to Rails 3"
One does not simply "Upgrade to Rails 3"
One does not simply "Upgrade to Rails 3"
Upcoming SlideShare
Loading in …5
×

One does not simply "Upgrade to Rails 3"

1,025 views

Published on

A talk given at the February SD Ruby meeting in San Diego, covering the issues one might face when upgrading a Ruby on Rails application from version 2.3 to 3.2.

Covers items deprecated or eliminated between versions, testing strategies, pain points, gotchas and general suggestions for making the transition across major versions of the Rails framework.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,025
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

One does not simply "Upgrade to Rails 3"

  1. 1. ONE DOES NOT SIMPLY UPGRADE TO RAILS 3
  2. 2. Adventures in Upgrading From Rails 2 to 3 Chris McCann @testflyjets github.com/testflyjets
  3. 3. The Task Upgrade a Rails 2.3.5 app to Rails 3.1 Ultimately upgrade to Rails 4
  4. 4. Why?
  5. 5. Benefits to Upgrading Security patches Ruby 2.0 New gems and capabilities, Bundler Asset pipeline + Sass Framework improvements, speed Improve test coverage (spoiler: easy!)
  6. 6. The App First app I ever built Started in 2007 Rails 1.2 initially Upgraded to 2.3.5 2nd Edition
  7. 7. The App ! Monkey-patched gems (mysql, geokit, DJ) Lots of plugins Prototype helpers...lots
  8. 8. The App CSS mess Homebrewed authentication
  9. 9. The App 163 models 167 controllers > 1,000 view templates 12,500 users Over $500,000 in non- profit transactions
  10. 10. Testing to the rescue!
  11. 11. Not so much
  12. 12. Resources for Upgrading Episodes 225, 226, 227
  13. 13. My Hybrid Approach* Create a new Rails 3 app Install Rails 3 versions of gems, replace plugins Get the framework running with config from old app The first goal is to get to: * Thanks to Rob Kaufman @ Notch8 $ rails console ! $ irb(main):001:0>
  14. 14. MySQL Originally MySQL 5.1 + mysql gem + monkey patch Not compatible with Rails 3 >> MySQL 5.5 + mysql2 Broke original app on dev machine because it can’t use MySQL 5.5 (bad handshake, disconnect errors) Solution: live with it (have 2nd dev machine)
  15. 15. Plugin > gem conversion Generally not too terrible Most plugins available as Rails 3 gems Can still use vendor/plugins if necessary Spoiler alert: you won’t find all the problems initially
  16. 16. Framework configuration Custom configuration code moved from environment.rb to application.rb Initializers used extensively in Rails 3 autoload paths (like /lib) need to be specified parameter filtering (passwords, credit card numbers) now in application.rb not in controllers Solution: just gut it out until things work
  17. 17. UDT: Upgrade Driven Testing
  18. 18. Tests as sanity checks Try to rapidly touch every model to trigger failures Tools of choice: rspec, factory_girl, spork, faker Script to generate specs and factories for all models: rails generate rspec:model #{model_file} -s
  19. 19. “Canary in a coal mine” tests I didn’t find a quick way to check my models Specs you don’t write are all “pending” Hidden land mine: attr_accessible
  20. 20. Model changes everywhere named_scope became scope plus syntax changes (deprecation) validates_* to validates (*attributes)! Had to update for rspec matchers to work ActiveModel find syntax changes (deprecation)
  21. 21. ActionMailer failer
  22. 22. ActionMailer methods Mailer methods changed: create_* and deliver_* are gone email = Mailer.confirm(user) email.deliver! @body[“instance_var”] to @instance_var
  23. 23. ActionMailer views Mailer views renamed: *.text.html.erb to *.html.erb *.plain.text.erb to *.text.erb! *.rhtml is completely deprecated, will fail Solution: easy to test them, trigger failures, fix ‘em Gotcha: links in your emails? How’s your routes.rb?
  24. 24. Routing changes
  25. 25. Joys of RESTful routing Original app had mix of RESTful and controller/action Bad, bad, bad: Catch-all route map.connect ‘:controller/:action/:id.:format’
  26. 26. Routing syntax tedium           flight.resource  :roster_import,  :controller  =>  :import,                :only  =>  [:new,  :create],              :member  =>  {  :import_csv    =>  :get,                                        :import_setup  =>  :get,                                        :match_imports  =>  :get  }                                           !        resource  :roster_import,  controller:  'import',     only:  [:new,  :create]  do              member  do                  get  'import_csv'                  get  'import_setup'                  get  'match_imports'              end          end                                        
  27. 27. Controller Testing Hoped for a straightforward way to sanity check request specs vs controller specs? rspec let() vs @var : association issues Bottom line: steep learning curve but necessary
  28. 28. Asset Pipeline Asset Pipeline partially implemented already Managed to double-include some files Watch out for relative paths between JS and CSS Overall: not terrible, probably easier without “poor man’s pipeline”
  29. 29. View booby traps Views can be a pain to test Over 1,000 view templates in the app ERB changes to look for: <% form_for ...%> to <%= form_for ...%>! Using raw to escape HTML built in strings (helpers)
  30. 30. No more Prototype helpers
  31. 31. Prototype helpers removed remote_form_for! form_remote_tag! link_to_remote! remote_function! Ajax form/links now done with remote: true
  32. 32. Prototype callbacks link_to_remote(dues.email_link, ! :url => send_notices_flight_dues_path(@flight, dues),! :before => "Element.show('spinner')",! :complete => "Element.hide('spinner')",! :method! => :post,! :confirm => confirm) ! ! ! link_to(dues.email_link, ! send_notices_flight_dues_path(@flight, dues),! remote: true, ! method: :post, ! confirm: confirm) !
  33. 33. Use jQuery for callbacks application.js! ! $("*[data-spinner]")! .on("ajax:before", function(){ ! $($(this).data('spinner')).show(); ! })! .on("ajax:complete", function(xhr, status){ ! $($(this).data('spinner')).hide(); ! })!
  34. 34. Geocoding and GMap Used geokit, monkey-patched for exception handling during auto-geocoding Google killed GMaps v2 last fall New geokit-rails for Rails 3: used v2, no “distance” field Solution: replace geokit-rails with geocoder
  35. 35. tl;dr Upgrading between major versions is hard Not having tests makes it MUCH harder Incremental upgrade is way easier For a large project, it simply takes time and effort Retrofit tests as you go -- you’ll need them someday
  36. 36. ONE DOES NOT SIMPLY UPGRADE TO RAILS 3
  37. 37. Adventures in Upgrading From Rails 2 to 3 Chris McCann @testflyjets github.com/testflyjets

×