Upgrading to Rails 3: Obstacles and helper scripts
Transferring an existing project to Rails 3 is not that hard, but it usually cannot be done in 5 minutes.
General upgrade approach
- Get the rails_xss plugin and adjust your
rawhelper calls till everything is fine again. - Check, if your plugins work at railsplugins.org.
- Get information about the changes and install the official rails_upgrade plugin. Run
rake rails:upgrade:backupto backup important files. Then runrake rails:upgrade:checkto analyse your project. The plugin displays useful information for various places where things need to be changed. It also has tasks for creating yourGemfile, updating your routes and configuration. But there is still some manual work required. I have written three little helper scripts that can assist you to solve some tasks. - When finished, replace some of the project’s Rails-specific files. You can do this by navigating to your project’s parent directory and running
rails my_project_nameas if you would want to create a new one. Then pick the files to overwrite.
Upgrade scripts
ERB syntax changes (the upgrade tasks complains about more, but this is wrong)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#!/usr/bin/env ruby # Upgrades all files in child directories to the new erb snytax in Rails 3 # Does not upgrade custom concatination helpers # See <https://asciicasts.com/episodes/208-erb-blocks-in-rails-3> for more info patterns = %w| fields_for form_for div_for content_tag_for field_set_tag form_tag remote_form_for form_remote_for form_remote_tag | # don't forget to update remote helpers to hash option: remote => true Dir['**/*.*'].each{ |filename| data = File.read filename File.open(filename,'w'){|f| f.print data.gsub(/<%\s+(#{ patterns*'|' }).*(do|\{)/){ $&.sub '<%', '<%=' } } } puts :Done
Add the config initializer to environment files
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#!/usr/bin/env ruby # add the AppName::Application.configure command to all config/environments/* files ENVIRONMENTS_PATH = 'config/environments/' APPLICATION_PATH = 'config/application.rb' if !File.exist? ENVIRONMENTS_PATH raise 'Please call the script from the Rails root directory' elsif !( File.exist?(APPLICATION_PATH) && ( File.read(APPLICATION_PATH) =~ /module\s+(\w+)/ ) && $1 ) raise "You need an already updated #{APPLICATION_PATH} to run this script" else app_name = $1 Dir[ENVIRONMENTS_PATH + '*'].each{|filename| lines = File.readlines filename unless lines.join =~ /#{app_name}::Application.configure/ lines.map!{|l|' ' + l} lines.unshift "#{app_name}::Application.configure do" lines << "end" File.open(filename,'w'){|file| file.print lines.join } end } puts :Done end
Updade cookie secret store
(the syntax gem really sucks…)
#!/usr/bin/env ruby
# Upgrades the session store. Only run this script, if you use cookies for
# session storage.
#
# This script is quite destructive and uses eval, so please check if
# your config/initializers/session_store.rb file looks like this:
#
# ActionController::Base.session = {
# :key => ‘_app_session’,
# :secret => ‘secret’
# }
#
# Please upgrade manually, if you have changed more than the values
SESSION_PATH = 'config/initializers/session_store.rb'
SECRET_PATH = 'config/initializers/cookie_verification_secret.rb'
if !File.exist? SESSION_PATH
raise 'Please call the script from the Rails root directory'
else
# get data
old = File.read SESSION_PATH
if matched = old =~ /ActionController::Base.session\s+=/
old[/ActionController::Base.session\s+=/] = ''
user_data = eval old
end
if !matched || !user_data.is_a?(Hash)
raise "#{SESSION_PATH} has changed too much, aborting..."
end
# write new files
File.open(SECRET_PATH,'w'){|file|
file.puts "Rails.application.config.secret_token = '#{user_data[:secret]}'"
}
File.open(SESSION_PATH,'w'){|file|
file.puts "Rails.application.config.session_store :cookie_store, :key => '#{user_data[:key]}'"
} if File.exists? SECRET_PATH
puts :Done
endSubtleties I had to deal with
Uninstall rails_xss
ActionView::Template::Error (undefined method `append=' for #<ActiveSupport::SafeBuffer:0xb6e2e4cc>)rails_xss is a Rails 2 plugin. Remove it after the upgrade.
Controller’s initialize method
After the upgrade, my views suddenly did not have any layouts, anymore! This was caused by overwriting the initialize method of a controller. Allowed in Rails 2, forbidden in version 3.
Add standard gems to Gemfile
In Rails 3, you need to put gems like sqlite and mongrel in your Gemfile, or they will not be used:
gem "sqlite3-ruby", :require => "sqlite3"
gem 'mongrel'Upgrade thin
/home/jan/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-3.0.0.beta3/lib/active_support/dependencies.rb:209:in `require': no such file to load -- dispatcher (LoadError)thin-1.2.5 is too old ;).
cache_template_loading
I had to remove this line from my config/environments/production.rb:
config.action_view.cache_template_loading = trueRails 3 Documentation
Rails 3 is updated almost every day and so do the docs change – so I relaunched PlasmaRails.org. It fetches Rails every day and generates its rdoc.
Working with Ruby
