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
2
Today We'll Cover:
Why Upgrade? Pain points / Issues Tips Take Aways
3
Full Disclosure
PriceChirp is my main side project designed to help people (myself included) save money on Amazon
My background is in Perl
4
Why???
Gem ecosystem is starting to require Rails 3.0 Too many deprecation notices
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
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
7
Source Control
Svn copy http://svn...com/pricechirp/trunk/ http://svn...com/pricechirp/branches/migrate_to_rails3
Svn checkout http://svn...com/pricechirp/branches/migrate_to_rails3 migrate
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
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
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
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"
12
Upgrade Gems
gem ‘will_paginate’, ‘~> 3.0.pre2’, :require => ‘will_paginate’
factory_girl_rails => compatibility mode
13
Passenger
Apache configuration changed from:
RailsEnv development to:
RackEnv development
14
Upgrade Plugins
Restful Authentication → Devise copy crypted_password => encrypted_password copy salt => encrypted_salt set confirmed date nil is a valid salt with Restful Auth, not in Devise Change helper methods
:login_required → :authenticate_user! logged_in? → user_signed_in?
Exception_notification
15
RAILS_ENV and RAILS_ROOT
RAILS_ENV → Rails.env Rails.env.production?
If RAILS_ENV == “production” If Rails.env.production?
RAILS_ROOT → Rails.root RAILS_CACHE → Rails.cache
16
XSS protection is everywhere
Learn to love .html_safe. All strings are not safe until flagged as safe.
17
Views
forms helpers changed from <% to <%= removed error_messages_for link_to_remote
Use :remote => true link_to
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
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
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
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
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
23
Custom to_s formatting for dates
Example: Time.now.to_s(:js) From:ActiveSupport::CoreExtensions::Time::Conversions::DATE_FOR
MATS.merge!(:js => ‘%m %d, %Y %H:%M:%S’)
To:
Time::DATE_FORMATS[:js] = ‘%m %d, %Y %H:%M:%S’
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
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
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
RSS
Had to wrap my “xml.description” output in a CDATA block for it to display
<![CDATA[
…
]]>
28
Validate-on-callback methods
validate_on_create
validate :x, :on => :create
29
Remove Debugging Statements
logger.info request.inspect
Rails 2.3.9 Rails 3.0
request.inspect 5.9k 330k
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
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
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
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
Thanks for Coming!
Steven Evatt
Email: [email protected]
Site: http://PriceChirp.com
Blog: http://www.evatt.com/blog
Twitter: @sevatt
Top Related