Riding the Rails 5.1 train

We’re very close to moving all of ManageIQ’s master branches to rails 5.1 with a goal of getting to rails 5.2 and eventually 6.0 after it’s released.

For rails 5.1, there have been several things we’ve fixed which are summarized below. The good news is that developers only need to run bin/update with each repository once we merge 5.1 on manageiq.

Please review the “important” sections. If you run into an issue with Rails 5.1, it’s likely one of the ones below. Let me know if you have any questions or if there’s a typo. Thanks!

Important Issues

  • Method each_with_object/each_value/each_key is deprecated and will be removed in Rails 5.1, as ActionController::Parameters no longer inherits from hash. Using this deprecated behavior exposes potential security problems. If you continue to use this method you may be creating a security vulnerability in your app that can be exploited. Instead, consider using one of these documented methods which are not deprecated: http://api.rubyonrails.org/v5.0.7/classes/ActionController/Parameters.html

  • The behavior of attribute_changed? inside of after callbacks will be changing in the next version of Rails. The new return value will reflect the behavior of calling the method after save returned

  • You are passing an instance of ActiveRecord::Base to find. Please pass the id of the object by calling id.

  • Cannot have a has_many :through association 'CloudNetwork#public_network_vms' which goes through 'CloudNetwork#public_network_routers' before the through association is defined

    • If you use a through association, you must define this association before trying to use it
    • PR1, PR2, PR3, PR4
  • The asset "svg/vendor-physical_infra_manager.svg" is not present in the asset pipeline.Falling back to an asset that may be in the public folder. This behavior is deprecated and will be removed. To bypass the asset pipeline and preserve this behavior, use the skip_pipeline: true option.

    • Sprockets tries to fetch an asset from the pipeline. If it’s not there, it logs this warning and tries the public folder. This happens in test even if you have no asset for it. Enabling live compilation in test helps most of these.

    • PR1, PR2

    • Enable live compilation of assets in test

Important Constant Problems

  • Passing a class to the class_name is deprecated and will raise an ArgumentError in Rails 5.2. It eagerloads more classes than necessary and potentially creates circular dependencies

  • Passing a class as a value in an Active Record query is deprecated and will be removed. Pass a string instead.

  • can't cast Class

    • find_by(:types => MyClass) becomes find_by(:types => MyClass.name), see here.
  • config.middleware.use accepts only a class now

    • config.middleware.use 'Thing' becomes config.middleware.use Thing, see here.

Less common problems

  • Rails 5.1 asserts all migrations written with 5.1+ use bigint/bigserial primary keys, while all prior version migrations use integer. We had to change this logic since we started using bigserial/bigint before it became hip.

  • Rails 5.1 switched from julian to gregorian calendar so 1.month and 1.year changed in value.

    • Affects charging where we have to make our assertion of 30.days in a month and 365.days in a year explicit, see here.
  • Support preloading of virtual attributes, see here.

  • 5.1 tests now track transactions across threads so setup/teardown can see what happened in other threads.

  • ActionView::Template::Handlers::Erubis is deprecated and will be removed from Rails 5.2. Switch to ActionView::Template::Handlers::ERB::Erubi instead

  • Passing string to be evaluated in :if and :unless conditional options is deprecated and will be removed in Rails 5.2

    • Use a symbol, lambda, proc, or block, see here.
  • association(true) to reload is gone

    • user.posts(true) becomes user.posts.reload
    • user.profile(true) becomes user.reload.profile
    • PR1, PR2
  • Locking a record with unpersisted changes is deprecated and will raise an exception in Rails 5.2. Use save to persist the changes, or reload to discard them explicitly, see here.

  • prepare_binds_for_database is gone, see here.

  • Fixes ambiguous source reflection for through, see here.

  • Non-kwargs support in AC::TestCase#post is gone, see here.

  • AR::QueryMethods uniq/distinct takes no block, see here.

  • sanitize_conditions is deprecated and will be removed from Rails 5.2, use sanitize_sql instead, see here.

3 Likes

We have some of our own custom interfaces that used this pattern. Should we eventually change those as well? For example, cache_with_timeout creates a memoized method with force_reload=false as a parameter.

Rails 5.1 has been merged. Please look out for any strange errors or issues and consult the list above. Let me know if I can help on any. Thanks!

Yes, great point. I remember thinking that when looking at this. We should definitely discuss if changing our interfaces that follow this pattern make sense.