Upgrading Rails 3.2 to Rails 4
You’ll need to be running Ruby 1.9.3 or later
Create New branch
$ git checkout -b rails4
Gemfile Changes:
Replace: gem 'rails', '3.2.x'
with: gem 'rails', '4.0.0.rc1'
Rails 4 removes 'assets' group, so remove assets group and change the gem version included in assets compatible to rails 4 like:
gem 'coffee-rails', '~> 3.2.1' => gem 'coffee-rails', '~> 4.0.0.rc1'
gem 'less-rails'
gem 'sass-rails', '~> 3.2.3' => gem 'sass-rails', '~> 4.0.0.rc1'
gem 'uglifier', '>= 1.0.3'
Now run "$ bundle update" to install new version of gems and "$ bundle outdated" to finding out of date gems. So update all the oudated gems to the version supported by Rails 4.
Ex: Let's say result of "$ bundle outdated" command is like,
Outdated gems included in the bundle:
* paper_trail (2.7.1 > 1.6.4)
.
.
.
Because it couldn’t find a newer version compatible with Rails 4 so just replace this gem like
gem 'paper_trail', github: 'airblade/paper_trail', branch: 'rails4'
and now run bundle update so it will fetch newer version of Papertrail from the Github project and completes successfully.
So just like that you have to update all outdated gems in your application with appropriate version.
Also page caching, observers, protected model attributes and ActiveResource have been removed in Rails 4. So if any of these features used in your application, then it's easy to add back through gems.
gem 'rails-observers'
gem 'actionpack-page_caching'
gem 'actionpack-action_caching'
gem 'activerecord-deprecated_finders'
Production environment in Rails 4 uses static precompiled assets and will not generate dynamically. So execute this command to precompile assets for production environment
$ RAILS_ENV=production bundle exec rake assets:precompile
Routes.rb File changes
'match' is not accepted in Rails 4.
There are two options for update match,
- Replace 'match' with appropriate request(get, post etc).
match 'new', to: 'inventories#new' => get 'new', to: 'inventories#new'
- 'via: [:get, :post]'
match 'new', to: 'inventories#new', via: :get
Replace 'put' => 'patch'
Configuration Changes
/config/application.rb
Replace
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
with: Bundler.require(:default, Rails.env)
Remove 'config.active_record.whitelist_attributes = false'
The asset pipeline is enabled by default in Rails 4, so need to set 'config.assets.enabled = false'
, if you are not using asset pipeline for your application, otherwise you can remove this option.
/config/development.rb
Set 'config.eager_load = false'
Remove 'config.whiny_nils = true'
Remove 'config.active_record.mass_assignment_sanitizer = :strict'
You can also remove the other options (like 'best_standards_support', 'auto_explain_threshold_in_seconds', 'assets.compress' etc..) which are no longer required.
/config/production.rb
Add 'config.eager_load = true'
Replace: 'config.assets.compress = true'
with: 'config.assets.js_compressor = :uglifier'
/config/test.rb
Add 'config.eager_load = false'
Remove 'config.whiny_nils = true'
Remove 'config.active_record.mass_assignment_sanitizer = :strict'
/config/initializers/secret_token.rb
Screencaster::Application.config.secret_token = '762a2f23950e306....'
Screencaster::Application.config.secret_key_base = 'xx762a2f23950e3..'
Once you’ve successfully migrated your application you can remove the secret_token option.
Models and controller level changes
In Rails 4, all scopes must use lambda:
Ex:
Replace: scope :active, where(status: 'active')
with: scope :active, -> { where(status: 'active') }
Clean up the deprecations
- find_all_by_
User.find_all_by_name('abc') => User.where(name: 'abc')
- find_last_by_
User.find_last_by_name('abc') => User.where(name: 'abc').last
- find_or_create_by_
User.find_or_create_by_name('abc') => User.where(name: 'abc').first_or_create
- find_or_create_by_...!
User.find_or_create_by_name!('abc') => User.where(name: 'abc').first_or_create!
- find_or_initialize_by_
User.find_or_initialize_by_name('abc') => User.where(name: 'abc').first_or_initialize - scoped_by_
User.scoped_by_name('abc') => User.where(name: 'abc')
Rails 4 use Strong parameter(strong parameter) So remove attributes from models and put the restrictions in the controller
Ex: Let's i have a product module
class Product < ActiveRecord::Base
attr_accessible :description, :image_url, :price, :title
has_many :product_events,:dependent => :destroy
end
and Product_controller
def create
@product = Product.new(params[:product])
respond_to do |format|
.
.
end
Remove first line from product model and create a private method in product controller
def product_params
params.require(:episode).permit(:description, :image_url, :price, :title)
end
and Replace: Product.new(params[:product])
with: Product.new(product_params)
Replace: before_filter'
with 'before_action'
Also the /vendor/plugins is no longer used so you can move the plugins out into a gem or into '/lib'.
There are many more Rails 4 features but i am exploring now so i will post in future.
Thanks
You can check the following link for more details: http://railscasts.com/episodes/400-what-s-new-in-rails-4(Rails 4 Feature)
Strong Parameter(Strong Parameter)