【问题标题】:ActiveRecord::Migration deprecation warning - asks for Rails version, but I'm not using RailsActiveRecord::Migration 弃用警告 - 要求提供 Rails 版本,但我没有使用 Rails
【发布时间】:2016-03-11 00:11:53
【问题描述】:

这是一个使用 ActiveRecord 与数据库对话的 Ruby 非 Web 项目。

有一个文件包含数据库连接代码、迁移和模型。请参阅此处(但不必阅读此内容来回答问题)

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

问题是关于这一行的:

class Migrations &lt; ActiveRecord::Migration

当我使用 Migrations.migrate(:up) 运行迁移时,我收到了弃用警告:

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]

就像它建议我将我的类定义更改为

  class Migrations < ActiveRecord::Migration[4.2]

然后我不再收到警告。

我想知道是否有人可以解释这样做的目的。

我的应用不依赖于任何版本的 Rails。为什么我需要

指定 Rails 版本?

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-5


    【解决方案1】:

    因为 Active Record 想知道迁移是在哪个版本中生成的。有时,迁移中的默认值可能会在 Rails 版本之间发生变化(当我说 Rails 版本时,我指的是 Rails 框架的版本,而不是 rails gem)。

    假设你有这样的迁移:

    create_table :todos do |t|
      t.string :content
    end
    

    它是使用 Active Record 4.2(以及 Rails 4.2 版本)生成的。在 Rails 4.2 中,字符串列的默认大小为 4 字节。 在 Rails 5.0 中,Rails 团队决定将默认大小更改为 8 字节。如果您将 gem 升级到 5.0,则回滚此迁移并再次运行,您的数据库将有一个 8 字节大小的字符串列。

    如果您在迁移中指定版本,则无论您使用哪个版本的 Active Record,该列将始终以生成的 Rails 版本中的默认大小生成。在我的示例中,如果您指定 4.2 作为版本,它将始终是一个 4 字节的字符串列。

    【讨论】:

    • 哇! @rafaelfranca!感谢您在这里解释.. ;) +1
    • 这是有道理的,尽管对于在 Rails 之外使用 AR 的人来说,这会让人感到困惑。
    • @rafaelfranca 关于 gem 维护者如何更新自动生成的迁移脚本以支持 Rails 4.1 和更早版本以及新的 Rails 迁移版本 API 的任何建议?我为此使用的解决方案很老套。例如:if Rails::VERSION::STRING[0..2].to_f &gt;= 5 active_record_migration_class = ActiveRecord::Migration[Rails::VERSION::STRING[0..2].to_f] else active_record_migration_class = ActiveRecord::Migration end 有什么更优雅的吗?
    【解决方案2】:

    如果从rails 4升级到rails 5,您可以在回滚或删除后将版本号添加到迁移中:

    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
    

    【讨论】:

    • 谢谢。我遇到了这个错误,只是在最后添加了版本,它清除了错误。虽然,就我而言,我必须在最后添加 [4.2],即使我正在运行 Rails 5.1.4。
    猜你喜欢
    • 2014-04-11
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 2012-02-23
    相关资源
    最近更新 更多