Migrating PriceChirp to Rails 3.0: The Pain Points
1. Migrating PriceChirp to Rails 3.0
Steven Evatt
Blog: http://www.evatt.com/blog
Web: http://PriceChirp.com
Twitter: @sevatt
Houston-RoR Nov 2010
The pain points
5. 5
How much work was it?
3 weeks of nights / weekends
According to svn
Paths added 67
Paths modified 112
Paths removed 45
Replaced Restful_Authentication with Devise
Converted from Prototype to UJS jQuery
6. 6
Where to start?
Upgrade to Rails 2.3.9
Upgrade Gems
Fix code to remove deprecation message
Bundler
Have test for critical functionality
Install Rails_upgrade plugin
Make a new branch in your source control
8. 8
Plugin → Rails_upgrade
Documentation out of order and gives wrong
syntax for rails command
Mostly run from rails 2.3
Useful rake tasks
Rake rails:upgrade:check
Rake rails:upgrade:backup
Rake rails:upgrade:routes
Rake rails:upgrade:gems
Rake rails:upgrade:configuration
9. 9
Installing Rails 3
Rails new .
Creates a rails3 project
with the name of the
current directory
If directory name is
migrate:
Application name is
Migrate::Application
Must update in 12 places
to change
10. 10
Bundler
Bundler manages an application's dependencies
through its entire life across many machines
systematically and repeatably.
Gemfile
gem “rack”, “~>1.1”
gem “rspec, :requires => “spec”
It doesn’t take long before you want to use
bundler on all projects
11. 11
Bundler II
Passenger is not ignoring my Gemfile :test,
:development block in production
To get bundler to work with capistrano:
Add to deploy.rb:
require "bundler/capistrano"
18. 18
UJS / jQuery
Converted rjs to erb
Converted from Prototype to jQuery
Get jQuery
− http://docs.jquery.com/Downloading_jQuery
− /public/javascripts/jquery-1.4.2.min.js
Copy rails.js from
github.com/rails/jquery-ujs/raw/master/src/rails.js
:remote => true
19. 19
Active Record Changes
passing options hash containing :conditions,
:include, :joins, :limit, :offset, :order,
:select, :readonly, :group, :having, :from,
:lock to any of the ActiveRecord provided
class methods, is now deprecated.
Find → where
find_by_x('xxx') => where(:x => ‘xxx’).first
where(‘b like ?’, value)
20. 20
Active Record “Bug”
select('distinct(x)') is ignored when passed to
.count
Example
Item.where('updated_at < ?',
1.days.ago ).select('distinct(asin)').all
Produces the following query:
Item Load (6.3ms) SELECT distinct(asin) FROM `items`
WHERE (updated_at < '2010-10-16 01:06:05')
21. 21
Active Record “Bug” II
Now, when we use .count instead of .all, the .select call
is ignored:
Item.where('updated_at < ?',
1.days.ago ).select('distinct(asin)').count
Yields:
SQL (5.4ms) SELECT COUNT(*) AS count_id FROM
(SELECT 1 FROM `items` WHERE (updated_at <
'2010-10-16 01:09:55')) AS subquery
22. 22
Active Record “Bug” III
Work around
Put a .all before the .count
Item.where('updated_at < ?',
1.days.ago ).select('distinct(asin)').all.count
Issue
If you attempt to use :group ie .count(:group => :asin) you
get an error
More Info on “bug”
https://rails.lighthouseapp.com/projects/8994/
tickets/5698-select-ignored-in-subquery-
when-querying-with-count
24. 24
Logging Rails.cache Activity
By default, Rails3 does not log Rails.cache activity
Cache read: user.default
Cache fetch_hit: user.default
Cache read: user.count ({:expires_in=>300 seconds})
Cache generate: user.count ({:expires_in=>300 seconds})
Cache write: user.count ({:expires_in=>300 seconds})
To enable logging
In environment.rb
Rails.cache.logger ||= Rails.logger
25. 25
Action Mailer
Action_mailer defaults to :smtp although
everything says it defaults to :sendmail
config.action_mailer.delivery_method = :sendmail
Action_mailer requires
default_url_options[:host] to be defined
config.action_mailer.default_url_options[:host] = {
:host => ‘pricechirp.com’ }
26. 26
script/* replaced by script/rails
script/rails replaces all the scripts that used to
be in the script directory
Safe to remove: about, console, dbconsole, destroy
generate, plugin, runner, and server
27. 27
RSS
Had to wrap my
“xml.description” output
in a CDATA block for it
to display
<![CDATA[
…
]]>
30. 30
Mime::Type
Error:
A ActionView::MissingTemplate occurred in pages#index:
Missing template pages/index with {:locale=>[:en, :en],
:handlers=>[:builder, :erb, :rjs, :rhtml, :rxml], :formats=>[:"text/*"]} in
view paths ….
actionpack (3.0.1) lib/action_view/paths.rb:15:in `find'
Solution:
In /config/initializers/mime_types.rb, add:
Mime::Type.register “text/*”, :html
31. 31
Current Issues I
A ActionController::UnknownHttpMethod occurred in #:
PROPFIND, accepted HTTP methods are get, head, put,
post, delete, and options actionpack (3.0.1)
lib/action_dispatch/http/request.rb:59:in `request_method'
32. 32
Current Issues II
Bundler – During a “cap deploy”
...
[pricechirp.com] executing command
** [out :: pricechirp.com] (in /home/pricechirp)
** [out :: pricechirp.com] Could not find gem 'rspec-rails (>= 2.0.1, runtime)' in any of
the gem sources.
** [out :: pricechirp.com] Try running `bundle install`.
command finished
*** [deploy:update_code] rolling back
...
33. 33
Take Aways
Upgrade / fix deprecated code as
best you can before you start
Use Rails_upgrade plugin
XSS Protection is everywhere
Syntax changes:
Views form helpers
Link_to_remote replaced with :remote => true
Active Record changes: .find → .where
Validate-on-callback
Configurations
There is a lot of deprecated
advice out there, remember
to check the dates
34. 34
Thanks for Coming!
Steven Evatt
Email: steven@evatt.com
Site: http://PriceChirp.com
Blog: http://www.evatt.com/blog
Twitter: @sevatt