ruby on rails upgrade — part 1

ruby rails upgrade

upgrade from 
ruby 2.2.0p0
rails 4.1.8
to
ruby 2.5.1
rails 5.2.3

Upgrade Change

  1. gemfile update

The very first step is to update the gems by changing the rails version gem file. Resolve the gem dependencies.

2. ajax-datatables-rails

From 
gem '
ajax-datatables-rails', '0.3'
to
gem 'ajax-datatables-rails', '1.0.0'

A code rewrite needs to be done. Remove the line from datatable class

include AjaxDatatablesRails::Extensions::Kaminari

3. sidekiq delay method

From
sidekiq '4.2.7'
to
sidekiq '5.2.3'

Add new if does n’t

Sidekiq::Extensions.enable_delay!

Add to

module LuesPhil  
class Application < Rails::Application
........
config.active_job.queue_adapter = :sidekiq
end
end

Remove highlighted lines from

Devise::Async.setup do |config|  
config.enabled = true
config.backend = :sidekiq
config.queue = :default

end

4.Country select gem

From
gem 'country_select'#, github: 'stefanpenner/country_select'
To
gem 'country_select', '~> 4.0'

Only gem upgrade

5.rails configuration update

Rails provides the app:update command (rake rails:update on 4.2 and earlier). After updating the Rails version in the Gemfile, run this command. This will help you with the creation of new files and changes of old files in an interactive session.

rails app:update

Don’t forget to review the difference, to see if there were any unexpected changes.

reference :
l

Files changed for me

modified: bin/bundle
modified: bin/rails
modified: config/application.rb
modified: config/boot.rb
new file: config/cable.yml
modified: config/environment.rb
modified: config/environments/development.rb
modified: config/environments/production.rb
modified: config/environments/test.rb
new file: config/initializers/application_controller_renderer.rb
modified: config/initializers/assets.rb
new file: config/initializers/content_security_policy.rb
modified: config/initializers/cookies_serializer.rb
new file: config/initializers/new_framework_defaults_5_2.rb
modified: config/initializers/wrap_parameters.rb
modified: config/locales/en.yml
modified: config/routes.rb
new file: config/storage.yml

So make sure that you have added you old config content into new config file.

6. Added application_record.rb

class ApplicationRecord < ActiveRecord::Base
self
.abstract_class = true
end

Changed my model file to inherit from application_record.

For example will look like

class AccessRole < ApplicationRecord  
end

7. PaperTrail syntax error

from
paper_trail (4.1.0)
a. PaperTrail.
whodunnit = "string"
b. self.touch_with_version
to
paper_trail (10.1.0)
a. PaperTrail.request
.whodunnit = "string"
b. self.paper_trail.save_with_version

8. before filter to before action and class to class name change

from 
before_filter :set_user_time_zone
to
before_action :set_user_time_zone

class name

from
has_many :patient_requests, class: Gdpr::PatientRequest
to
has_many :patient_requests, class_name: ‘Gdpr::PatientRequest’

9. attr_encrypted gem

from 
attr_encrypted (1.3.4)
to
attr_encrypted (3.1.0)

code change is need look below

11. quiet_assets : This gem is deprecated

12. activesupport-json_encode gem (no longer required )

A pure-Ruby ActiveSupport JSON encoder. This was the default encoder used by ActiveSupport prior to Rails 4.1. The main advantage of using this encoder over the new default is for the #encode_json support (see below).

// Parsing this in JavaScript in the browser
JSON.parse("{\"big_number\":12345678901234567890.0}").big_number // => 12345678901234567000

13. Allowing hash value in params and retrieve hash values from params

In controller

params.require(:manager).permit(
:first_name,
:last_name,
:dob,
:gender,
:email,
:phone_number,
roles: {} ).tap do |attributes|
attributes[:roles] = attributes[:roles].to_h.collect do|key,value|
value
end
end

14. Datatable
Datatable started throwing an error

Uncaught TypeError: Cannot use ‘in’ operator to search for ‘length’ in

Found that jquery-rails got updated to latest(jquery-rails (4.3.3)) through gem file and datatables was in a asset folder without update.

Changed to datatables (1.10.19). Fixed.

So if you face the issue check for datatables release and their jquery supported version

For example

  • Update: To jQuery 1.11.1
  • Fix: Compatiblity with jQuery 1.7.x

15. ckeditor

After upgrade to latest v4.3.0 in rails 5.2.3 faced an issue which is similar mentioned in

ActionController::RoutingError (No route matches [GET] “/assets/ckeditor/plugins/copyformatting/lang/en.js”

Tried again and faced issue said by download copyformatting and install, can solve it but now i get new problem

Uncaught TypeError: Cannot read property ‘17’ of undefined

A solution said by

Just don’t use vendor, use ckeditor by CDN. This works.

Another approach we tried is through Bower and faced difficulties in enabling ckeditor and custom config (custom config.js).

If you enabled
config.action_controller.action_on_unpermitted_parameters = :raise
in application.rb point 16, 17 and 18 will occur

16. devise Invitable gem

rymai commented on Jan 7, 2011

@manager.skip_password = truedef password_required?    
!persisted? || !password.nil? || !password_confirmation.nil?
end
New Changedef password_required?
!@skip_password && (!persisted? || !password.nil? || !password_confirmation.nil?)
end

17. .build is only with new

// creating a new comment
def new
blog = Blog.find(params['id']
blog.build_comments.save
end
// comments already created and trying to update
def edit
blog = Blog.find(params['id'])
// blog.build_comments.save // Throw an error for Edit
blog.comments.save //this will work
end

18. Rails strong/permitted params

rails will block params which is not mentioned in permitted params

def blog_params
params[:blog].require(:blog_attributes).permit(:title, :subject, :body)
end

Nested params

rails was blocking nested params. Let you explain if your form is nested form with nested field then permitted params should have nested filed mentioned ( shown in an example below )or else rails will through an error.

def blog_params
params[:blog].require(:blog_attributes).permit(:title, :subject, :body, comments_configuration_attributes:[:name, :comment])
end

19. Rails belongs_to

Model with acts_as_tenant fails validation after Rails 5 update (added Presence Validator when model contain acts_as_tenant(:tenant) )

Have you tried the `optional: true` options when specifying acts_as_tenant?```
class InputForm < ApplicationRecord
acts_as_tenant :tenant, optional: true
end
```
OR
You can configure your rails 5 application like so```
# config/application.rb
...
module YourProject
class Application < Rails::Application
...
# Make the belongs_to value as false by default in Rails 5
config.active_record.belongs_to_required_by_default = false
...
end
end
```

20. jQuery ready() Method
Few jQuery and script which was working without ready() Method in 4 have stopped working in 5. That should be taken care of.

21. gem ‘paper_trail’

We moved from papertrial gem v3.0.9 to v10.3.1

1. 
- self.touch_with_version
+ self.paper_trail.save_with_version2.v3.0.9
example : object.save
# Generates a version for a `touch` event (`widget.touch` does NOT generate a version)
v10.3.1
object.save creates the version

22. gem ‘paperclip’
To get the uploaded file name in paperclip

- file_name = self.attachment.file.original_filename      + file_name = self.attachment.file.filename

23. redirect_to back in rails 5

- redirect_to :back

+ redirect_back fallback_location: root_path

24. devise gem

- if user.confirm! && user.save    + if user.confirm && user.save

25. Arel node change

def view_columns
||= {
..
start_date: {source: "Training.start_date", cond: new_search_condition},
..
}rails 4def new_search_condition
..
casted_column = ::Arel::Nodes::NamedFunction.new('to_char', [tzdate, "Mon DD, YYYY"])
...
endrails 5casted_column = ::Arel::Nodes::NamedFunction.new("to_char", [tzdate, build_node("Mon DD, YYYY")])def build_node val
::Arel::Nodes.build_quoted val
end

arel reference:

26. jquery “ ”

- $('.nav-tabs a[href='+hash.replace(prefix,"")+']').tab('show');    + $('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');

27. In rails 4, if image is missing then it will raise the warning, but in rails5 throws an error. So add the image if code has. This applies to file aswell. example : style.css

- background: url('img/timesine/delete.png') no-repeat top center;  comment out the image is not requied or not available+ /*background: url('img/timesine/delete.png') no-repeat top center;*/

28. Rails 4.2.2 vs Rails 5.0.2 JSON Storage with PG

rails 4
result.to_json
rails 5
JSON.parse(result)
This behavior is because to fix the issue .
Please use
OrderItem.new(options: JSON.parse("{\"key\":\"value\"}")).

In Console (Rails 4.2.2)

item = OrderItem.new(options: "{\"key\":\"value\"}")
=> #<OrderItem id: nil, options: {"key"=>"value"}>
item.options
=> {"key"=>"value"}
item.options.is_a?(String)
=> false
item.options.is_a?(Hash)
=> true

In Console (Rails 5.0.2)

item = OrderItem.new(options: "{\"key\":\"value\"}")
=> #<OrderItem id: nil, options: "{\"key\":\"value\"}">
item.options
=> "{\"key\":\"value\"}"
item.options.is_a?(String)
=> true
item.options.is_a?(Hash)
=> false

29. Issues with path of services folder/eager loading path.

Change from autoload path to eager load.
Eager loading requires a detailed path like directory, subdirectory.

rails 4config.autoload_paths += Dir[..."#{config.root}/services_list/", "#{config.root}/mailer_service"...]rails 5
config.eager_load_paths += Dir[....."#{config.root}/services_list/", "#{config.root}/services_list/active_service","#{config.root}/mailer_service".......]

30. Migration [5.0]
Used in order to run the migration file in rails5 which is generated in rails4.

- class AddIsDeleteToProfile < ActiveRecord::Migration + class AddIsDeleteToProfile < ActiveRecord::Migration[5.0]

31. gem ‘rubyXL’ # for parsing excel sheets

Deprecated extract_data, so copy a method into local file from gem

class I18n::ConvenienceMethod  
class << self
def extract_data worksheet
worksheet.sheet_data.rows.map { |row| row.cells.map { |c| c && c.value() } unless row.nil? }
end
end
end
def sheet_data
workbook = RubyXL::Parser.parse(I18n::LocaleManager::FILE)
worksheet = workbook[SNF::LetterTranslation::S_NO]

- questions = worksheet.extract_data //rails4
+ questions = I18n::ConvenienceMethod.extract_data(worksheet) //rails5
end

32. Few gem into rails core and few deprecates

a. quiet_assets,
Replacing the quiet_assets gem with sprockets-rails

reference :

b. activesupport-json_encoder,
c. activerecord-postgresql-citext

reference :

are default in rails5

progressive_render is not supported in rails5

33. mina application deployment tool

If you have the mina in rails4 and upgrading to rails5 then a list of files needs an update.

a. config/deploy/*environment.rb

b. project_folder/config/deploy.rb

34. acts_as_tenant gem

rails 4
validates :sub_domain, unique: true
rails 5
validates_uniqueness_of :sub_domain

35. reform gem

rails 4
validates :sub_domain, uniqueness: true
rails5
validates :sub_domain, unique: true

Added additional gem “reform-rails” when using reform gem with rails 5

36. parameterize — syntax change

rails 4
'cts_' + value.parameterize('_')
rails 5
'cts_' + value.parameterize(separator:'_')

37. config/environments/development.rb
In a development environment changes made in the file is not available until the setting up the ActiveSupport::FileUpdateChecker

rails 4
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
rails 5
config.file_watcher = ActiveSupport::FileUpdateChecker

About Configuration wise upgrade

Reference :

Upgrade from rails 4.2 to 5.0

Tech blogger..