Notes on upgrading Rails from 3.2 to 4.0
Posted on January 7th, 2015
The upgrade itself is not that hard. The main thing is the change from models protected from mass-assignment to strong parameters in the controllers. The rest is fairly quick and simple.
Here are more detailed notes:
- Strong parameters: Use the gem in 3.2 and move any attr_accessible out of your models. Ensure you added the 
config.active_record.whitelist_attributes = falseto your application.rb. The work is mostly moving whatever was attr_accessible in a model to the appropriate controller that creates that model using thepermitsyntax.
All of your mass assignment tests and code disappears. Hopefully your controllers were already doing some checking on valid params. Otherwise, make sure you write loads of tests to transfer your mass assignment restrictions to your controllers. - Tests now have to respect strong parameters requirements so 
post :createandput :updatewill no longer work. You’ll have to add valid params in your tests. I recommend just using alet :valid_params { whatever }with RSpec. - Scopes need lambdas instead of plain where clauses. So look for any 
scope :symbol, where(…)and replace it withscope :symbol, lambda{ where(...) }. - Regular expressions with $ and ^ now show warnings to be replaced by \z and \A respectively.
 - Old 
link_to ... :confirmnow have to becomelink_to ..., data: {confirm: …} - Model queries that ended with 
.allor.sumhave to become either.loador, mostly, just.to_ato force loading and use arrays instead of the lazy query. - Many application config changes. Going through 
rake rails:upgradehelps a long way but don’t just let it override your stuff. Ensure you choose diff and verify what should and shouldn’t be overwritten. - Gems that were in an assets group have to move out of it and just be in the main list. You can add 
:require => falseafter the gem in your Gemfile if you are worried about memory usage in production (as most assets will be precompiled before production). - Parameter filters have their own initializers now (out of application.rb). The rake task should show you that.
 - Routes no longer can use 
match. Replace byget,post,patchordelete. - The validation options 
:presence => trueand:allow_blank => truedon’t really play well together anymore. If you require presence, it cannot be blank. Otherwise change your require presence to be conditional (and your allow blank too). Something along the lines ofvalidate :name, :presence => { :if => lambda {|m| model.condition? } }, :allow_blank => { :if => lambda {|m| m.condition?} }. 





