Use Synvert to automatically upgrade rails 4.2 to 5.0 (Part 1) (you are here)
Use Synvert to automatically upgrade rails 4.2 to 5.0 (Part 2)
Use Synvert to automatically upgrade rails 4.2 to 5.0 (Part 3)
Rails is one of the most popular web application frameworks, rails team releases a new version every year. In this tutorial series, I will demonstrate how to use Synvert to automatically upgrade your Rails application from 4.2 to 5.0.
The first one is versioned migrations.
When you run the db:migrate
task in rails 5.0, you will see the following warning:
Directly inheriting from ActiveRecord::Migration is deprecated. Please specify the Rails release the migration was written for:
So we need to change all migrations to inherit from ActiveRecord::Migration[4.2]
instead of ActiveRecord::Migration
.
To get started with Synvert, open VSCode and activate the Synvert Extension. Select the language as ruby
and click “Show Generate Snippet Form”.
Set the File Pattern as db/migrate/*.rb
Set the Gem Version as activerecord >= 5.0
Set the Input as
class CreatePosts < ActiveRecord::Migration
end
and Output as
class CreatePosts < ActiveRecord::Migration[4.2]
end
Finally, click the “Generate Snippet” button. This will generate the following snippet:
Synvert::Rewriter.new 'group', 'name' do
if_gem 'activerecord', '>= 5.0'
within_files 'db/migrate/*.rb' do
with_node node_type: 'class', name: 'CreatePosts', parent_class: 'ActiveRecord::Migration' do
replace :parent_class, with: '[4.2]'
end
end
end
This is a simple and straightforward snippet that searches for the class
node whose name
is CreatePosts
and parent_class
is ActiveRecord::Migration
, and replaces the parent_class
with {{parent_class}}[4.2]
. To make it works with all migrations, we just need to remove the rule that name
is CreatePosts
. So the updated snippet is as follows:
Synvert::Rewriter.new 'group', 'name' do
if_gem 'activerecord', '>= 5.0'
within_files 'db/migrate/*.rb' do
with_node node_type: 'class', parent_class: 'ActiveRecord::Migration' do
replace :parent_class, with: '{{parent_class}}[4.2]'
end
end
end
Now we can search in our project
And replace them with ActiveRecord::Migration[4.2]
.
The next one is ApplicationRecord
Active Record Models Now Inherit from ApplicationRecord by Default
It requires us to make two changes:
add a new file
app/models/application_record.rb
.change all models to inherit from
ApplicationRecord
instead ofActiveRecord::Base
.
Open the VSCode Synvert Extension. Select the language as ruby
and click “Show Generate Snippet Form”.
Set the File Pattern as app/models/**/*.rb
Set the Gem Version as activerecord >= 5.0
Set the Input as
class Post < ActiveRecord::Base
end
and Output as
class Post < ApplicationRecord
end
Click the “Generate Snippet” button, then it will generate the following snippet:
Synvert::Rewriter.new 'group', 'name' do
if_gem 'activerecord', '>= 5.0'
within_files 'app/models/**/*.rb' do
with_node node_type: 'class', name: 'Post', parent_class: 'ActiveRecord::Base' do
replace :parent_class, with: 'ApplicationRecord'
end
end
end
It searches for the class
node whose name
is Post
and parent_class
is ActiveRecord::Base
, then replaces the parent_class
with ApplicationRecord
. To make it works with all models, we just need to remove the rule that name
is Post
.
The updated snippet is as follows:
Synvert::Rewriter.new 'group', 'name' do
if_gem 'activerecord', '>= 5.0'
within_files 'app/models/**/*.rb' do
with_node node_type: 'class', parent_class: 'ActiveRecord::Base' do
replace :parent_class, with: 'ApplicationRecord'
end
end
end
Now we can search in our project.
And replace them with ApplicationRecord
.
To add the app/models/application_record.rb
file, we can use the add_file
api to let synvert create the file automatically.
add_file 'app/models/application_record.rb', <<~EOS
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
EOS
We can do the same thing for ApplicationMailer
and ApplicationJob
.
That concludes this tutorial. In the next tutorial, I’ll show you more cases when upgrading rails from 4.2 to 5.0. See you then!
Share this post