Upgrading Rails Versions: 4.1.8 to 4.2.0
After a lot of interruptions for other work, last week I finally finished recreating my CMS app in Rails 4 - just in time for the release of Rails 4.2! Most of the information I have been reading about 4.2 has focused on new features, adequate record, foreign keys, active job, etc. So I was not really prepared for a number of issues that came up as a result of changes and depreciations. On my first pass, 871 of my 1419 tests failed! So guess I had better take some notes as I go along.
To get started, I changed the Rails version in my Gemfile from 4.1.8
to 4.2.0 and ran bundle upgrade rails
and then ran my rspec test
suite (rspec-rails 3.1.0 with rspec-core 3.1.2). As I said, a TON of
tests failed, including the vast majority of my controller tests.
SSL Requirement
All (or nearly all) of the controller test failures pointed to my SSL-requirement gem. I need to go back and diagnose that - but since I can’t easily actually run SSL on my dev server right now, I commented out the gem in my Gemfile and include lines in my application controller:
Deprecation Warnings
New Configuration Options
Each time I run my tests, I was getting a couple of deprecation warnings, one about renaming a configuration option serve_static_assets to serve_static_files and one about suppressing errors raised within after_rollback and after_commit callbacks. The first one was fairly easy to deal with. I just searched my config directory and changed the option name in my test.rb and production.rb files. It isn’t set in development.rb so I continued to leave it out.
For the second warning, I tried adding an option in each of my 3 environments files - setting the option to true for dev and test but keeping the old exception suppression by setting this to false in my production.rb file.
Unfortunately, setting those options did not fully suppress the
deprecation warnings. I am still getting them for all 4 of the models
I have that use paperclip (my documents model and all 3 of my image
type models). Before reporting an issue, I thought I would try
upgrading to the latest version of paperclip. Running bundle update
paperclip
upgraded me from paperclip 4.2.0 to 4.2.1 and cocaine 0.5.4
to 0.5.5. And that did remove the remaining
‘raise_in_transactional_callbacks’ warnings when I run my tests!!!
Truthiness
One of my tests had several instances of the following warning:
All of these were coming from sections of the test where I was doing a create or update with invalid parameters. I had not given much thought to those params but assigned a nonsense value to one of my boolean columns:
The model in question is not super picky, so it is a little difficult to find parameters that would invalidate the model. For my create actions, sending in an empty file attribute would invalidate the model object. But for an update, an empty file would be perfectly legitimate since one can update other attributes without uploading a new file. But, since I am mocking out the save action to return false in my ‘update with invalid params’ tests, it is good enough.
Page Versions
When running the pages controller spec, I got a bunch of warnings about serialized_attributes. I suspect those are coming from my versioning system, paper_trail. But I noticed that there is also a new version of the tree plugin I use, closure tree. Looking at the changelog, I didn’t see anything that looked like it would make any difference but decided to upgrade anyway so as to keep up; this took me from closure_tree 5.0.0 to 5.2.0.
Upgrading paper_trail from 3.0.5 to 3.0.6 did not make any difference in the serialized_attributes warnings:
Looking at the issue queue, I guess I should have known about this for quite a while: https://github.com/airblade/paper_trail/issues/416 There doesn’t seem to be any consensus about a solution. For now I think I’ll ignore it - even though it means my page controller and versions controller specs are kind of noisy.
Errors
Changes to assert_select
Almost all of my request specs and a bunch of my view specs are failing with messages like:
Mass Upgrade of Gems
Fiddling with a few gem updates didn’t seem to be making any difference to this, so I decided to move my Gemfile.lock to Gemfile.lock.bak (for reference) and let bundler install the latest compatible versions of things. This made the following updates:
I also commented out coffee-rails because I am not using coffeescript; this removed the coffee-rails, coffee-script-source, and subexec gems.
This upgrade took care of most of the errors I was seeing in my view specs. The few remaining problems pointed out actual errors - mostly some form tags that had been copied over from the rails 2.3 version of this project. I also had an error in the user mailer - again due to misuse of url_for to get an https url. I fixed those and now all of my model, mailer, routing, controller, helper, and view tests pass. So now it is just my request specs that are dorked:
Defining document_root_element
All the remaining errors still refer to document_root_element not being implemented. Grepping through the gems in my Rails 4.2 gemset, most references come from a new gem, rails-dom-testing. The README for the gem shows an example of using document_root_element - and refers us to the API docs in selector_assertions.rb. But even after reading that, I am somewhat unclear about what to do.
More poking around - by searching on github - turned up 2 pull requests: https://github.com/rails/rails/pull/17107 and https://github.com/rails/rails-dom-testing/pull/20 Again, very confusing but suggesting the need to add an alias to html_document - temporarily?
I looked at the other places where I found document_root_element in my rails 4.2 gemset. All 3 were places where a method by that name was defined, one each in actionpack-4.2.0/lib/action_controller/test_case.rb, actionpack-4.2.0/lib/action_dispatch/testing/integration.rb, and actionview-4.2.0/lib/action_view/test_case.rb. Two out of 3 of those defined it as:
So I tried dropping that into one of my test files and that caused the tests in that file to pass.
To include this in all my request specs, I created a module and included it only in my request specs:
With that addition, almost all of my request specs passed. I had a couple of places (in request specs and in my view specs) where I needed to change my html entities to the characters they evaluate to - as warned about in the release notes: http://edgeguides.rubyonrails.org/4_2_release_notes.html#assert-select After taking care of those issues, all my tests pass again!
Other
I still haven’t figured out the SSL requirement errors. But that is for another post.
After that, I may still want to look into rest of the release notes to see if there is anything else I should examine: And I should read through the upgrade guide to see what else I might want to deal with. There is also an intro to Rails 4.2 video
- though I suspect that will be about the new features and not about some of the refactoring or internal changes.