Skip to content

Commit

Permalink
Drop support for Ruby < 3.0 and Rails < 7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
fatkodima committed Jan 11, 2025
1 parent a055d7f commit 1dcef24
Show file tree
Hide file tree
Showing 19 changed files with 57 additions and 133 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ jobs:
strategy:
matrix:
include:
- ruby-version: 2.7
gemfile: activerecord_61.gemfile
- ruby-version: 2.7
- ruby-version: 3.0
gemfile: activerecord_70.gemfile
- ruby-version: 2.7
- ruby-version: 3.0
gemfile: activerecord_71.gemfile
- ruby-version: 3.0
gemfile: activerecord_72.gemfile

- ruby-version: 3.4
gemfile: activerecord_80.gemfile
Expand Down
5 changes: 4 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ require:
- rubocop-disable_syntax

AllCops:
TargetRubyVersion: 2.7
TargetRubyVersion: 3.0
NewCops: enable
SuggestExtensions: false

Expand Down Expand Up @@ -87,6 +87,9 @@ Style/RescueStandardError:
Style/MultipleComparison:
ComparisonsThreshold: 3 # default is 2

Style/ArgumentsForwarding:
Enabled: false

Style/DisableSyntax:
DisableSyntax:
- unless
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## master (unreleased)

- Drop support for Ruby < 3.0 and Rails < 7.0

## 0.22.0 (2025-01-03)

- Make background data migrations scheduler run a single migration at a time
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PATH
remote: .
specs:
online_migrations (0.22.0)
activerecord (>= 6.1)
activerecord (>= 7.0)

GEM
remote: https://rubygems.org/
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ See [comparison to `strong_migrations`](#comparison-to-strong_migrations)

## Requirements

- Ruby 2.7+
- Rails 6.1+
- Ruby 3.0+
- Rails 7.0+
- PostgreSQL 9.6+

For older Ruby and Rails versions you can use '< 0.11' version of this gem.
For older Ruby and Rails versions you can use older versions of this gem.

**Note**: Since some migration helpers use database `VIEW`s to implement their logic, it is recommended to use `structure.sql` schema format, or otherwise add some gem (like [scenic](https://github.com/scenic-views/scenic)) to be able to dump them into the `schema.rb`.

Expand Down
5 changes: 0 additions & 5 deletions gemfiles/activerecord_61.gemfile

This file was deleted.

7 changes: 1 addition & 6 deletions lib/online_migrations/background_migrations/migration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,7 @@ class Migration < ApplicationRecord

alias_attribute :name, :migration_name

# Avoid deprecation warnings.
if Utils.ar_version >= 7
enum :status, STATUSES.index_with(&:to_s)
else
enum status: STATUSES.index_with(&:to_s)
end
enum :status, STATUSES.index_with(&:to_s)

belongs_to :parent, class_name: name, optional: true, inverse_of: :children
has_many :children, class_name: name, foreign_key: :parent_id, dependent: :delete_all, inverse_of: :parent
Expand Down
7 changes: 1 addition & 6 deletions lib/online_migrations/background_migrations/migration_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,7 @@ class MigrationJob < ApplicationRecord
scope :except_succeeded, -> { where.not(status: :succeeded) }
scope :attempts_exceeded, -> { where("attempts >= max_attempts") }

# Avoid deprecation warnings.
if Utils.ar_version >= 7
enum :status, STATUSES.index_with(&:to_s)
else
enum status: STATUSES.index_with(&:to_s)
end
enum :status, STATUSES.index_with(&:to_s)

delegate :migration_name, :migration_class, :migration_object, :migration_relation, :batch_column_name,
:arguments, :batch_pause, to: :migration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,7 @@ class Migration < ApplicationRecord

alias_attribute :name, :migration_name

# Avoid deprecation warnings.
if Utils.ar_version >= 7
enum :status, STATUSES.index_with(&:to_s)
else
enum status: STATUSES.index_with(&:to_s)
end
enum :status, STATUSES.index_with(&:to_s)

belongs_to :parent, class_name: name, optional: true, inverse_of: :children
has_many :children, class_name: name, foreign_key: :parent_id, inverse_of: :parent
Expand Down
10 changes: 3 additions & 7 deletions lib/online_migrations/command_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,7 @@ def rename_column(table_name, column_name, new_column, **)
table_name: table_name,
column_name: column_name,
new_column: new_column,
model: table_name.to_s.classify,
partial_writes: Utils.ar_partial_writes?,
partial_writes_setting: Utils.ar_partial_writes_setting,
enumerate_columns_in_select_statements: Utils.ar_enumerate_columns_in_select_statements
model: table_name.to_s.classify
end
end

Expand Down Expand Up @@ -394,9 +391,8 @@ def change_column(table_name, column_name, type, **options)
end

def change_column_default(table_name, column_name, _default_or_changes)
if Utils.ar_partial_writes? && !new_column?(table_name, column_name)
raise_error :change_column_default,
config: Utils.ar_partial_writes_setting
if ActiveRecord::Base.partial_inserts && !new_column?(table_name, column_name)
raise_error :change_column_default
end
end

Expand Down
8 changes: 4 additions & 4 deletions lib/online_migrations/error_messages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ class <%= model %> < ApplicationRecord
<%= column_name.to_s.inspect %> => <%= new_column.to_s.inspect %>
}
}
<% unless partial_writes %>
<% unless ActiveRecord::Base.partial_inserts %>
NOTE: You also need to temporarily enable partial writes (is disabled by default in Active Record >= 7)
until the process of column rename is fully done.
# config/application.rb
config.active_record.<%= partial_writes_setting %> = true
config.active_record.partial_inserts = true
<% end %>
2. Deploy
Expand All @@ -148,7 +148,7 @@ def change
end
4. Replace usages of the old column with a new column in the codebase
<% if enumerate_columns_in_select_statements %>
<% if ActiveRecord::Base.enumerate_columns_in_select_statements %>
5. Ignore old column
self.ignored_columns += [:<%= column_name %>]
Expand Down Expand Up @@ -247,7 +247,7 @@ def down
to be inserted when changing the default value of a column.
Disable partial writes in config/application.rb:
config.active_record.<%= config %> = false",
config.active_record.partial_inserts = false",

change_column_null:
"Setting NOT NULL on an existing column blocks reads and writes while every row is checked.
Expand Down
20 changes: 0 additions & 20 deletions lib/online_migrations/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,6 @@ def index_name(table_name, column_name)
"#{short_name}#{hashed_identifier}"
end

def ar_partial_writes?
ActiveRecord::Base.public_send(ar_partial_writes_setting)
end

def ar_partial_writes_setting
if Utils.ar_version >= 7.0
"partial_inserts"
else
"partial_writes"
end
end

def ar_enumerate_columns_in_select_statements
if ar_version >= 7
ActiveRecord::Base.enumerate_columns_in_select_statements
else
false
end
end

# Returns estimated rows count for a table.
# https://www.citusdata.com/blog/2016/10/12/count-performance/
def estimated_count(connection, table_name)
Expand Down
23 changes: 3 additions & 20 deletions lib/online_migrations/verbose_sql_logs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module VerboseSqlLogs
class << self
def enable
@activerecord_logger_was = ActiveRecord::Base.logger
@verbose_query_logs_was = verbose_query_logs
@verbose_query_logs_was = ActiveRecord.verbose_query_logs
return if @activerecord_logger_was.nil?

stdout_logger = ActiveSupport::Logger.new($stdout)
Expand All @@ -23,30 +23,13 @@ def enable
end

ActiveRecord::Base.logger = combined_logger
set_verbose_query_logs(false)
ActiveRecord.verbose_query_logs = false
end

def disable
ActiveRecord::Base.logger = @activerecord_logger_was
set_verbose_query_logs(@verbose_query_logs_was)
ActiveRecord.verbose_query_logs = @verbose_query_logs_was
end

private
def verbose_query_logs
if Utils.ar_version >= 7.0
ActiveRecord.verbose_query_logs
else
ActiveRecord::Base.verbose_query_logs
end
end

def set_verbose_query_logs(value) # rubocop:disable Naming/AccessorMethodName
if Utils.ar_version >= 7.0
ActiveRecord.verbose_query_logs = value
else
ActiveRecord::Base.verbose_query_logs = value
end
end
end
end
end
4 changes: 2 additions & 2 deletions online_migrations.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
spec.summary = "Catch unsafe PostgreSQL migrations in development and run them easier in production"
spec.homepage = "https://github.com/fatkodima/online_migrations"
spec.license = "MIT"
spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
spec.required_ruby_version = Gem::Requirement.new(">= 3.0")

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
Expand All @@ -20,5 +20,5 @@ Gem::Specification.new do |spec|
spec.files = Dir["**/*.{md,txt}", "{lib}/**/*"]
spec.require_paths = ["lib"]

spec.add_dependency "activerecord", ">= 6.1"
spec.add_dependency "activerecord", ">= 7.0"
end
18 changes: 6 additions & 12 deletions test/command_checker/change_column_default_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ def change

def test_with_partial_writes
with_partial_writes(true) do
if ar_version >= 7
assert_unsafe ChangeColumnDefault, <<~MSG
Partial writes are enabled, which can cause incorrect values
to be inserted when changing the default value of a column.
Disable partial writes in config/application.rb:
assert_unsafe ChangeColumnDefault, <<~MSG
Partial writes are enabled, which can cause incorrect values
to be inserted when changing the default value of a column.
Disable partial writes in config/application.rb:
config.active_record.partial_inserts = false
MSG
else
assert_unsafe ChangeColumnDefault, <<~MSG
config.active_record.partial_writes = false
MSG
end
config.active_record.partial_inserts = false
MSG
end
end

Expand Down
40 changes: 18 additions & 22 deletions test/command_checker/misc_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,39 +210,35 @@ def test_rename_column_without_partial_writes
NOTE: You also need to temporarily enable partial writes (is disabled by default in Active Record >= 7)
until the process of column rename is fully done.
# config/application.rb
config.active_record.#{OnlineMigrations::Utils.ar_partial_writes_setting} = true
config.active_record.partial_inserts = true
MSG
end
end

def test_rename_column_with_enumerate_columns_in_select_statements
skip if ar_version < 7
previous = ActiveRecord::Base.enumerate_columns_in_select_statements
ActiveRecord::Base.enumerate_columns_in_select_statements = true

begin
previous = ActiveRecord::Base.enumerate_columns_in_select_statements
ActiveRecord::Base.enumerate_columns_in_select_statements = true

assert_unsafe RenameColumn, <<~MSG
5. Ignore old column
assert_unsafe RenameColumn, <<~MSG
5. Ignore old column
self.ignored_columns += [:name]
self.ignored_columns += [:name]
6. Deploy
7. Remove the column rename config from step 1
8. Remove the column ignore from step 5
9. Remove the VIEW created in step 3 and finally rename the column:
6. Deploy
7. Remove the column rename config from step 1
8. Remove the column ignore from step 5
9. Remove the VIEW created in step 3 and finally rename the column:
class FinalizeCommandChecker::MiscTest::RenameColumn < #{migration_parent}
def change
finalize_column_rename :users, :name, :first_name
end
class FinalizeCommandChecker::MiscTest::RenameColumn < #{migration_parent}
def change
finalize_column_rename :users, :name, :first_name
end
end
10. Deploy
MSG
ensure
ActiveRecord::Base.enumerate_columns_in_select_statements = previous
end
10. Deploy
MSG
ensure
ActiveRecord::Base.enumerate_columns_in_select_statements = previous
end

class RenameColumnNewTable < TestMigration
Expand Down
6 changes: 1 addition & 5 deletions test/schema_statements/misc_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,10 @@ def teardown
end

def test_schema
if ActiveRecord.version >= Gem::Version.new("7.0.2")
assert_nothing_raised do
ActiveRecord::Schema[ar_version].define do
add_index :users, :name
end
else
ActiveRecord::Schema.define do
add_index :users, :name
end
end
end

Expand Down
3 changes: 1 addition & 2 deletions test/support/minitest_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ def with_safety_assured(&block)
end

def with_partial_writes(value, &block)
setting = OnlineMigrations::Utils.ar_partial_writes_setting
ActiveRecord::Base.stub(setting, value, &block)
ActiveRecord::Base.stub(:partial_inserts, value, &block)
end

def with_postgres(major_version, &block)
Expand Down
9 changes: 2 additions & 7 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def self.env
end

if OnlineMigrations::Utils.ar_version < 7.1
ActiveRecord::Base.legacy_connection_handling = false
ActiveRecord.legacy_connection_handling = false
end

# Disallow ActiveSupport deprecations sprouting from this gem
Expand All @@ -56,12 +56,7 @@ def self.env
#
# Another option is to suggest users to set/unset `ignored_columns` when needed, but since
# partial writes are enabled by default, no action from users will be needed.
ActiveRecord::Base.public_send("#{OnlineMigrations::Utils.ar_partial_writes_setting}=", true)

# Was added in https://github.com/rails/rails/pull/41718.
if OnlineMigrations::Utils.ar_version >= 7
ActiveRecord::Base.enumerate_columns_in_select_statements = false # default in 7.0
end
ActiveRecord::Base.partial_inserts = true

def prepare_database
connection = ActiveRecord::Base.connection
Expand Down

0 comments on commit 1dcef24

Please sign in to comment.