Rails Upgrade: From 4.0 to 6.1 to 7.1 and Ruby 2.0 to 3.0 to 3.1.3
In the ever-evolving world of web development, keeping your tech stack up-to-date is crucial. Legacy frameworks like Rails often require migration to their latest versions to harness new features, security patches, and performance enhancements. As the complexity and size of your application grow, so does the challenge of ensuring a smooth upgrade process.
Having recently undertaken the task of upgrading several large-scale applications, I found myself faced with a multitude of errors and warnings during the Rails and Ruby version transitions. In this comprehensive guide, I’ll walk you through each issue I encountered and share the practical solutions that allowed me to successfully migrate these projects. Whether you’re a seasoned developer or just starting, this article will equip you with the knowledge and insights needed to tackle similar upgrades effectively and confidently.
Following is a long list of Errors you might get in your application.
1. ERROR
undefined method `attr_accessible’ for #<Class:0x00007f78e46861b8> (NoMethodError) (protected_attributes_continued)
Solution
Add protected_attributes_continued gem used to solve this problem, we have used attr_accessible to make them strong.
2. Error
uninitialized constant ActiveMerchant::Billing::Integrations (NameError)
Solution:
Link: https://stackoverflow.com/questions/38822616/uninitialized-constant-activemerchantbillingintegrationshelper-nameerror
work-done:
added gem ‘offsite_payments’, ‘~> 2.7’, ‘>= 2.7.11’
ActiveMerchant::Billing::Integrations change to OffsitePayments::Integrations
files:
config/environments/automation.rb:43
config/application.rb:141
3. Error
GEM offsite_payments added got the following warning .
In order to use `offsite_payments` gem, you need to either install or add to your Gemfile
Solution:
one of the two options for Money gem:
- `gem ‘money’`
- `gem ‘shopify-money’, require: ‘money’`
Regardless of which gem you choose, please add them *before* `offsite_payments`.
For more info, go to
Link: https://github.com/activemerchant/offsite_payments#money-gem-dependency
It’s also important to note that all Money object usage inside `offsite_payments` is being deprecated. We encourage you to use your own Money object inside your app instead of relying on `offsite_payments` doing it for you, e.g. `Money.from_amount(notification. gross)
4. Error
Error undefined method cache storage for Image Uploader:Class rails
Solution:
Upgrade the version of carrierwave gem from (0.11.0) to (2.2.2)
carrierwave_backgrouder is (0.4.2) (year 2015) stopped maintaining
5. Error
config/puma.rb:5:in `_load_from’: undefined method `daemonize’ for #<Puma::DSL:0x00007fdc2a297b98> (NoMethodError).
Reason: Puma > 5.0 = Demonization has been removed without replacement
Solution:
reference_link: https://stackoverflow.com/questions/67735620/puma-undefined-local-variable-or-method-daemonize-error
added in gem file: gem ‘puma-daemon’, require: false
and in the Puma.rb file
require ‘puma/daemon’
daemonize false Downgraded the gem to original version
6. Error:
undefined method `whodunnit=’ for PaperTrail:Module (NoMethodError)
Reason:
version update from (8.1.2) to (10.3.1)
solution:
config/initializers/paper_trail.rb
change PaperTrail.whodunnit to PaperTrail.request.whodunnit
7. Error:
no implicit conversion of Rack::Session::SessionId into String
Solution:
app/controllers/application_controller.rb:650
data[:session] = {id: Base64.encode64(session.id), ttl: $redis.ttl(“session:#{session.id}”)} if session.present?
TO
data[:session] = {id: Base64.encode64(session.id.to_s), ttl: $redis.ttl(“session:#{session.id}”)} if session.present?
8. Error:
undefined method `name’ for #<ISO3166::Country:0x00007f8043dc5e68> Coming from Country Gem
Solution: #{country.name}. To #{country.common_name}
9. Error: uninitialized constant RailsParam::Param
Reason: gem rails_params upgrade from (0.10.0) to (1.3.0)
Solution:
rescue_from RailsParam::Param::InvalidParameterError do |exception|
To
rescue_from RailsParam::InvalidParameterError do |exception|
10. Error:
uninitialized constant ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES (NameError)
Reason: deprecated
reference_link: https://gitlab.com/gitlab-org/gitlab foss/-/merge_requests/18240
Solution:
BOOL_VALUES = ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES + ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES
TO
BOOL_VALUES = ActiveModel::Type::Boolean::FALSE_VALUES
11. Error:
uninitialized constant ActionDispatch::ParamsParser::DEFAULT_PARSERS (NameError)
Solution:
ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::YAML)
TO
ActionDispatch::Request.parameter_parsers = ActionDispatch::Request.parameter_parsers.except(:json) ActionDispatch::Request.parameter_parsers = ActionDispatch::Request.parameter_parsers.except(:json)
12. Error:
NoMethodError: assigns have been extracted to a gem. To continue using it,
add `gem ‘rails-controller-testing’` to your Gemfile.
Solution: Added: gem ‘rails-controller-testing’
13. Error: NoMethodError: undefined method `new’ for BigDecimal:Class
Solution: Added : gem ‘bigdecimal’, ‘1.3.0’
14. undefined method `enabled?’ for #<PaperTrail::ModelConfig:0x00007feed5dfca98>
Solution:
change klass.paper_trail.enabled? To klass.paper_trail.present?
15. ERROR:
Failure/Error: it { should ensure_length_of(:message).is_at_most(PaymentModel::MESSAGE_MAX_LENGTH) } NoMethodError:undefined method `ensure_length_of’ for #<RSpec::ExampleGroups::Payment::BehavesLikePayments::MessageValidation:0x00007fedc97451d0>
Reference_link: https://stackoverflow.com/questions/20771314/rspec-should-ensure-length-of-allow-nil
Solution: ensure_length_of is deprecated use validate_length_of
16. ERROR:
Failure/Error: it { should ensure_inclusion_of(:status).in_array(Transaction::STATUS.keys) }
NoMethodError:
undefined method `ensure_inclusion_of’ for #<RSpec::ExampleGroups::Transaction_2::BehavesLikeTransactions::Status:0x00007fc86cd75640>
Reference_link:https://stackoverflow.com/questions/11697597/rails-rspec-why-does-this-validates-inclusion-of-role-in-wone-two
Solution: ensure_inclusion_of TO validates_inclusion_of
17. Error: before{ Plan.skip_callback(:validation, :before, :set_name)}
ArgumentError: Before validation callback :set_name has not been defined
Link: https://github.com/thoughtbot/factory_bot/issues/931
Solution: before{ Plan.skip_callback(:validation, :before, :name, raise: false)} added raise: false.
Reason: ActiveSupport::Callbacks#skip_callback now raises an ArgumentError if an unrecognized callback is removed. → new version
18. ERROR: Failure/Error: let(:community) { create(:community) }
ArgumentError:
wrong number of arguments (given 1, expected 0; required keywords: force, in_after_callback, is_touch)
Solution:
self.paper_trail.record_update(true)
TO
self.paper_trail.record_update(force: true, in_after_callback: true, is_touch: true)
link: https://www.rubydoc.info/gems/paper_trail/PaperTrail%2FRecordTrail:record_update
19. NameError:uninitialized constant Faker::TwinPeaks
Change
Faker::TwinPeaks TO Faker::TvShows::TwinPeaks
Link: https://www.rubydoc.info/gems/faker/Faker/TvShows/TwinPeaks
20. Error
Undefined method enabled?
it's Deprecated.
Change version_id: klass.paper_trail.enabled? ? self.versions.last.id : nil)
TO
version_id: PaperTrail::Request.enabled_for_model?(klass) ? self.versions.last.id : nil)
21. Error:
undefined method `process_dirty_object’ for #<FundraiserCampaign:0x00007fb06bf15860>
Did you mean? Process_failure
Solution: gem ‘acts-as-taggable-on’, ‘~> 8.1.0’ downgrade to 4.0.0 as gem deprecated method process_dirty_object and there is no alternative.
22. Failure/Error: expect(fc).not_to be_valid
Reason: In Rails 5 when you store a float value followed by .0 it will take it as an integer value and round it off.
23. Error: permitted params
Rails 5 now has permitted params, which doesn’t care about the HASH name. It only deals with What’s inside the hash and with a key pair permitted: true
24. Error:
Faker::GameOfThrones change to Faker::TvShows::GameOfThrones in new gem update.
25. Error:
#RAILS5 If you give any random string or number to a boolean field it will be automatically true.
26. Error:
NoMethodError:undefined method `can?’ for nil:NilClass
Solution: it needs Signed_in user. before { sign_in(:user, user) }
27. Error:
When you are passing root key in the Render call it will not recognised until you put adapter: :json
Before: format.json { render json: annotations.map(&:to_hash), root: “rows” }
After: format.json { render json: annotations.map(&:to_hash), root: “rows”, adapter: :json }
28. Error:
RSpec when you have String keys Hash and you pass it to a variable like
let(:google_ads_lead_params) = {
“api_version”: “1.0”,
“form_id”: 12320204771,
“google_key”: “001f81b4857599fb9ee974323bb30a6b”,
“is_test”: true,
“creative_id”: 30000000000}
It will convert HASh String keys to Symbol keys.
29. Error: In Rails 5 if you check a parent object is valid. It will give you true if the object is valid?
even if its Parent.child object in invalid.
30: Error: `failure_message_for_should_not` is deprecated. Use `failure_message_when_negated` instead.
`failure_message_for_should` is deprecated. Use `failure_message` instead.
31. DEPRECATION WARNING: `config.static_cache_control` is deprecated and will be removed in Rails 5.1.
Please use
`config.public_file_server.headers = { ‘Cache-Control’ => ‘public, max-age=3600’ }`instead.
32. DEPRECATION WARNING: ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement Remove Following
config.active_record.raise_in_transactional_callbacks = true
32. DEPRECATION WARNING: #table_exists? currently checks both tables and views. This behavior is deprecated and will be changed with Rails 5.1 to only check tables. Use #data_source_exists? instead. (called from <top (required)
33. DEPRECATION WARNING: before_filter is deprecated and will be removed in Rails 5.1. Use before_action instead.
34. Error: cannot load such file — i18n/core_ext/hash (LoadError)
Solution: Issue with chewy gem, has to put a patch on it. That it should use
require ‘active_support/core_ext/hash’
NOT
require ‘i18n/core_ext/hash’
Link:https://github.com/toptal/chewy/compare/master...chrisandreae:chewy:remove-i18n-refinement
35: Error: undefined method `parent’ for Lend::Engine:Class (NoMethodError)
Solution: parent is deprecated we have to use
module_parent to get the parent class name.
Link: https://apidock.com/rails/v6.0.0/Module/parent
36: Error: undefined method `to_prepare’ for ActionDispatch::Reloader:Class (NoMethodError)
Did you mean? To_param
Solution: ActionDispatch::Reloader.to_prepare is deprecated, now it’s coming from.
ActiveSupport::Reloader.to_prepare
Link: https://api.rubyonrails.org/v6.1.4.1/classes/ActiveSupport/Reloader.html
38: Error: undefined method `raise_in_transactional_callbacks=’ for ActiveRecord::Base:Class ActiveSupport::Deprecation.warn(‘ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.’)
Solution: We have to remove all following lines from our project.
config.active_record.raise_in_transactional_callbacks = true
Link: https://api.rubyonrails.org/v5.0.7.2/
Link: https://stackoverflow.com/questions/28006358/undefined-method-raise-in-transactional-callbacks-for-activerecordbaseclass
39. Error:
Unknown key: :on. Valid keys are: :if, :unless, :prepend (ArgumentError)
Case 1:
before_save :create_campaign_update, on: :create
Change TO
before_create :create_campaign_update
Case 2:
before_save :create_campaign_update, on: :update
Change TO
before_update :create_campaign_update
Link: https://github.com/rails/rails/issues/17622
40. Error:
uninitialized constant PaperTrail::Rails::Engine (NameError)
Solution: remove PaperTrail::Rails::Engine.eager_load! From config/initializers/paper_trail.rb
41: Error:
undefined method `track_associations=’ for #<PaperTrail::Config:0x00007f7a795eb8c0> (NoMethodError)
Solution: Method Removed from 12.3.0 paper_trail version.
Link: https://www.rubydoc.info/gems/paper_trail/12.3.0/PaperTrail/Config
42: Error: `parameterize’: wrong number of arguments (given 1, expected 0) (ArgumentError)
Solution: sources.map { |p| p.parameterize(“_”) }
Change TO
sources.map { |p| p.parameterize(separator: “_”) }
link: https://apidock.com/rails/v6.1.3.1/ActiveSupport/Inflector/parameterize
43: Error: A class was passed to `:class_name` but we are expecting a string.
In Rails 6 :Class_name key in Association only accepts strings. Not Class name.
Link: https://stackoverflow.com/questions/52583879/a-class-was-passed-to-class-name-but-we-are-expecting-a-string
44: Error:
Passing string to be evaluated in :if and :unless conditional options is not supported. Pass a symbol for an instance method, or a lambda, proc or block, instead. (ArgumentError)
Solution: Change the String Conditions to LAMBDA FUNCTION.
45: Error: undefined method `before_filter’ for Devise::SessionsController:Class (NoMethodError) Did you mean? before_action
Solution: change before_filter TO before_action
link: https://stackoverflow.com/questions/45015651/undefined-method-for-before-filter
46: Error: wrong number of arguments (given 0, expected 3) (ArgumentError)
due to best_in_place gem
Docs says to update the gem
Solution: For Rails >= 6.1 you can install the gem from this repository with:
gem “best_in_place”, git: “https://github.com/mmotherwell/best_in_place"
Link: https://github.com/bernat/best_in_place
47. Error:
Passing string to be evaluated in :if and :unless conditional options is not supported. Pass a symbol for an instance method, or a lambda, proc or block, instead
Solution:
validates :url, presence: true, if: “self.link? || self.video?”
Change To
validates :url, presence: true, if: -> {self.link? || self.video?}
Link: https://stackoverflow.com/questions/42495133/rails-validation-if-one-condition-is-true
48. Error:
undefined method `before_filter’ for Admin::DonationCampaignsController:Class
Replace all your usages of before_filter To before_action
Link: https://apidock.com/rails/ActionController/Filters/ClassMethods/before_filter
49.Error:
*** ActiveRecord::UnknownAttributeReference Exception: Query method called with non-attribute argument(s): “position(name in ‘razorpay,payu,paytm,paytm_qr,citrus’)”
Change
@pgs = PaymentGateway.where(name: pg_names).order(“position(name in ‘#{pg_names.join(“,”)}’)”)
TO
@pgs = PaymentGateway.where(name: pg_names).order(Arel.sql(“position(name in ‘#{pg_names.join(“,”)}’)”))
50. Error:
ArgumentError: unknown keywords: :campaign_id, :id
Solution:
Rails 6 don’t accept key value pair in params
You have to Wrap up params into hash with the key value params: {param1: “a”, param2: “b”}
51. Error: undefined method `xhr’ for #<RSpec::ExampleGroups::BasketItemsController::DestroyBasketItem::WhenUserIsLoggedIn:0x00007fbeb541d1a8>
Change
xhr :post, :create, {“basket_item”=>{“currency”=>”inr”, “item_id”=>”4381", “item_type”=>”Loan”, “amount_money”=>”600"}}
TO
post :create, params: {“basket_item”=>{“currency”=>”inr”, “item_id”=>”4381", “item_type”=>”Loan”, “amount_money”=>”600"}}, xhr: true
Link: https://stackoverflow.com/questions/6394787/rails-testing-xhr-with-post-data
52. Error: undefined method ‘Fomats’ did you mean format.
Related to Spec issue.
Solution: have to upgrade Spec version according to The Rails 6.
Rspec-rails from 3.5.2 to 4.0.0
53. Error:
Failure/Error: render nothing: true
ActionView::MissingTemplate:
Missing template anonymous/show, application/show with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :arb, :coffee, :rabl]}. Searched in:
*”#<RSpec::Rails::ViewRendering::EmptyTemplateResolver::ResolverDecorator:0x00007f7f03ac9a98>”
Change
def show
render nothing: true
end
TO
def show
head :ok, content_type: “text/html”
end
Link: https://stackoverflow.com/questions/4632271/render-nothing-true-returns-empty-plaintext-file
54. Error:
Failure/Error: expect(response.content_type).to eq(“application/json”)
Reason:
expected: “application/json”.
got: “application/json; charset=utf-8”
(compared using ==)
charset=utf-8. Comes in Rails 6.
Link: https://stackoverflow.com/questions/65642974/ruby-on-rails-setting-content-type-in-responds-to-f-f-any
55. Error:
Failure/Error: expect(response).to be_success
expected #<ActionDispatch::TestResponse:0x00007fe1e41df0d8 @mon_data=#<Monitor:0x00007fe1e41df038>, @mon_data_…@request=#<ActionController::TestRequest GET “http://test.host/fundraisers/occaecati1" for 0.0.0.0>> to respond to `success?`
CHANGE:
expect(response).to be_success
To
expect(response).to have_http_status(:success)
Link: https://stackoverflow.com/questions/55402791/expected-the-response-to-have-a-success-status-code-2xx-but-it-was-401
56. Error:
Lamda is not working in active_admin files along with scope we change it to Proc
Change:
scope :my_campaigns, show_count: false, if: lambda { |o| current_user.managed_projects.count > 0 }
to
scope :my_campaigns, show_count: false, if: proc { |o| current_user.managed_projects.count > 0 }
57. Error: Cannot call expect! Method on action params directly we have to convert in hash.
Change:
Params[:user].except!
To
Params[:user].to_unsafe_h.except!
58. Error:
Cannot add Errors message directly
Change:
errors[:pricing_plan] = “cannot be changed for the campaign which is not verfied.”
TO
errors.add(:pricing_plan, :not_implemented, message: “cannot be changed for the campaign which is not verfied.”)
59. Error: Rails.application.routes.url_helpers we have to prefix it with all the routes helpers its a rails 6.1 bug.
60. Error: Uniq will not work anymore change it to distinct
61.
Ruby_dep was on 1.5.0 which doesn’t have further support. So I have to remove it. And listen 3.1.5 gem version is using ruby_dep have to upgrade it from 3.1.0 to 3.0.0 Where it stops using ruby_dep as its dependency.
62. Webrick gem is eliminated from ruby 3.0.0 and snapshot is using it as its dependency so have to install it explicitly.
Link: https://stackoverflow.com/questions/65617143/cannot-load-such-file-webrick-httputils
63. Have to upgrade active admin from 2.6.1 to 2.9.0 as it's not compatible with realities core gem for rails 6.1.7.2
64. Active_recod is not compatible with Paper_trail
upgraded the Paper_trail gem 10.3.0 to 10.3.1.
65. Activestorage-validator version was not compatible with rails so have to upgrade it from 0.1.2 to 0.1.3
66. we have to delete ruby_dep as there is no new support for this gem
67. Bullet gem does not support active_record 6.1.7.2 yet Bullet gem upgrade from 6.1.0 to 6.1.5.
Link: https://github.com/flyerhzm/bullet/issues/566
68. A visible warning comes when we run the server from the paper trail has to upgrade it overall to paper trail to 12.0.0
69. after solving point 68. Got the following Error
So to solve this we have to upgrade paper_trail-association_tracking gem from 2.0.0 to 2.2.1
70. There is a big difference between ruby 3.0 and 2.7.5 regarding positional and keyword References. Ruby3.0 doesn’t support hash in keyword arguments.
In Rails 5, ruby 2.7.5
In Rails 6.1.7.2, ruby 3.0
ERROR we got in our console. This is going to be a big difference as we are using keyword arguments frequently in our project so we have to change to code base. Also, we have to upgrade all gems to be on specific versions where they are using Ruby 3.0 if they are using keyword arguments.
Ruby 3.0 deprecates automatic conversion from a hash to keyword arguments
71. Faced issue related active_storage gem,
to fix run below commands;
rails active_storage:update
rails db:migrate
72. In admin panel faced below issue due to pagination(kaminari gem).
To fix had to remove the version from gemfile.
Old: gem “kaminari”, “~> 1.2.0”
New: gem “kaminari”
73. Below CSS related issues were found. In order to fix this, had to remove “;” from all sass files + indentations had to be matched compared to the rest of the files.
74. Rspec-rails gem version issue was causing feature failures.
To fix had to update the gem version to 4.1.0 from 3.7
75. We have to change update_attribute to update as it’s removed from all over the rails 6.1.
Link: https://blog.saeloun.com/2019/04/15/rails-6-deprecates-update-attributes.html
meeting.update_attribute(“compliant”,meeting.curricula_curriculum_speaker_groups.non_compliant.blank?)
TO
meeting.update(“compliant” => meeting.curricula_curriculum_speaker_groups.non_compliant.blank?)
76. DEPRECATION WARNING: ActiveModel::Errors#keys are deprecated and will be removed in Rails 7.0.
Fix applied was: errors.keys is replaced with “errors.attribute_names”
Link: https://github.com/pantographe/view_component-form/issues/89
77. WARN Selenium [DEPRECATION] [:caps_browsers] Remote::Capabilities.chrome is deprecated. Use Options.chrome instead.
The fix applied was that the selenium driver register was updated. As per the reference link.
78. Whenever there was an error capybara failed to take screenshots with error;
In order to fix this, Had to capybara-screenshot configuration as below:
Capybara::Screenshot.register_driver(:headless_chrome) do |driver, path|
driver.browser.save_screenshot(path)
end
Link: https://github.com/mattheworiordan/capybara-screenshot/issues/211
79. Faced deprecation warning: WARN Selenium [DEPRECATION] [:capabilities] The :capabilities parameter for Selenium::WebDriver::Chrome::Driver is deprecated. Use :options argument with an instance of Selenium::WebDriver::Chrome::Driver instead.
Replaced :capabilities with :options
80. During feature spec run faced => warning: control_d_handler’s arity of 2 parameters was deprecated (eval_string, pry_instance). Now it gets passed just 1 parameter (pry_instance)
In order to fix updated “pry-byebug” gem version from 3.8.0 to 3.9.0
Link: https://medium.com/williamdesk/upgrade-ruby-on-rails-project-101-f4c1b44ec254
81. Active storage Controllers
class BaseController < ActiveStorage::BlobsController
TO
class BaseController < ActiveStorage::Blobs::RedirectController
class BaseVariantsController < ActiveStorage::RepresentationsController
TO
class BaseVariantsController < ActiveStorage::Representations::BaseController
82. Generating image variants requires the image_processing gem. added `gem ‘image_processing’, ‘~> 1.2’` to Gemfile.
83. Updated activeadmin gem from 2.9.0 to 2.12.0 as it’s not compatible with ruby 3.0 not supporting key word attribute.
84. Failure/Error: expect(response.content_type).to eq(“text/csv”)
expected: “text/csv”
got: “text/csv; charset=utf-8”
(compared using ==)
We have to add.
charset=utf-8. Comes in Rails 6.
86. Has to convert strings into symbols as rails 6 will not recognize it.
87. Was facing missing attribute error from all registration site specs. After digging through the code, found that it was related to the geocoder near method where it was unable to fetch the distance. Googled, found a solution and applied the same for all registration sites.
Ref link: https://github.com/alexreisner/geocoder/issues/42#issuecomment-25129503
88. After merge/joining mets venues table, It was not fetching all attributes from meetings table. Had to fetch columns specifically.
89. Hemlibra site showing routing error for .css file. Had to convert .css file to .scss file.
90. In Rails 6 where.not conditions are changed.
91. Changed active storage service URL syntax.
92. After upgrading the newrelic agent gem started facing stack level too deep issue.
Fix applied as per : https://docs.newrelic.com/docs/apm/agents/ruby-agent/troubleshooting/systemstackerror-stack-level-too-deep/
93. Autoload constants issue(zeitwerk mode) in rails 6
To fix this, added config.autoloader = :classic in env file.
94. During the deployment, faced an issue with assets:precompile related to rexml.
To fix this had to add rexml gem specifically to the gemfile.
95. Faced stack level too deep error during active storage file upload and download process.
In order to fix this issue,
replaced gem “rack-mini-profiler”, “~> 2.2”, require: false -> gem “rack-mini-profiler”, “~> 2.2”, require: [‘prepend_net_http_patch’] in Gemfile