This is a Ruby non-web project that uses ActiveRecord to talk to the database.
There is a single file which contains the db connection code, migration, and model. See here (but it's not necessary to read this to answer the question)
require 'sqlite3'
require 'active_record'
require 'yaml'
require 'active_support/all'
require 'securerandom'
BasePath = "#{File.dirname(__FILE__)}/.."
DATABASE_FILENAME = "database.sqlite"
DATABASE_PATH = "#{BasePath}/#{DATABASE_FILENAME}"
SQLite3::Database.new(DATABASE_PATH)
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: DATABASE_PATH
)
class Migrations < ActiveRecord::Migration
def up
create_table :todos do |t|
t.string :content
t.boolean :completed
t.timestamps null: false
end
end
def down
puts "backing up database".red_on_black if File.file?(DATABASE_PATH)
loop { (`cp #{DATABASE_PATH} #{DATABASE_PATH}-#{SecureRandom.urlsafe_base64}.backup`; break) rescue next }
sleep 0.5
drop_table :todos
puts "dropped todos table"
end
end # Migrations
class Todo < ActiveRecord::Base
end
The question is about this line:
class Migrations < ActiveRecord::Migration
When I run the migration with Migrations.migrate(:up)
, I get a deprecation warning:
DEPRECATION WARNING: Directly inheriting from ActiveRecord::Migration is deprecated.
Please specify the Rails release the migration was written for:
class Migrations < ActiveRecord::Migration[4.2]
Like it advises I change my class definition to
class Migrations < ActiveRecord::Migration[4.2]
And then I no longer get the warning.
I'm wondering if anyone can explain the purpose of this.
My app doesn't depend on any version of Rails. Why would I need
to specify a Rails version?
Because Active Record wants to know in which version the migrations were generated. Sometimes a default in a migration can change between Rails releases (when I say Rails releases I'm talking about the release of Rails the framework, not rails the gem).
So let's say you have a migration like:
create_table :todos do |t|
t.string :content
end
And it was generated with Active Record 4.2 (and thus Rails 4.2 release). In Rails 4.2, strings columns have the default size of 4 bytes. In Rails 5.0, the Rails team decided to change the default size to 8 bytes. If you upgrade the gem to 5.0 rollback this migration and run again now your database will have a string column with 8 bytes of size.
If you specify the version in the migration, no matter which version of Active Record you are using the column will always be generated with the size that were the default in the version of Rails that it was generated. In my example, if you specify 4.2 as the version it will be always a 4 bytes string column.
If upgrading from rails 4
to rails 5
, you can just add the version number to the migration like so after rollback or drop:
Rails 4.2.6
class CreateStudents < ActiveRecord::Migration
def change
create_table :students do |t|
t.belongs_to :user, index: true
t.string :first_name
t.string :last_name
t.string :phone
t.timestamps null: false
end
end
end
Rails 5.1.3
class CreateStudents < ActiveRecord::Migration[5.1]
def change
create_table :students do |t|
t.belongs_to :user, index: true
t.string :first_name
t.string :last_name
t.string :phone
t.timestamps null: false
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With