lib/strong_migrations/checks.rb in strong_migrations-2.0.2 vs lib/strong_migrations/checks.rb in strong_migrations-2.1.0
- old
+ new
@@ -8,11 +8,11 @@
table, expression = args
if !new_table?(table)
if postgresql? && options[:validate] != false
add_options = options.merge(validate: false)
- name = options[:name] || @migration.check_constraint_options(table, expression, options)[:name]
+ name = options[:name] || connection.check_constraint_options(table, expression, options)[:name]
validate_options = {name: name}
if StrongMigrations.safe_by_default
safe_add_check_constraint(*args, add_options, validate_options)
throw :safe
@@ -226,36 +226,34 @@
def check_change_column_null(*args)
table, column, null, default = args
if !null
if postgresql?
- safe = adapter.constraints(table).any? { |c| c["def"] == "CHECK ((#{column} IS NOT NULL))" || c["def"] == "CHECK ((#{connection.quote_column_name(column)} IS NOT NULL))" }
+ constraints = connection.check_constraints(table)
+ safe = constraints.any? { |c| c.options[:validate] && (c.expression == "#{column} IS NOT NULL" || c.expression == "#{connection.quote_column_name(column)} IS NOT NULL") }
unless safe
# match https://github.com/nullobject/rein
constraint_name = "#{table}_#{column}_null"
- add_code = constraint_str("ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s IS NOT NULL) NOT VALID", [table, constraint_name, column])
- validate_code = constraint_str("ALTER TABLE %s VALIDATE CONSTRAINT %s", [table, constraint_name])
- remove_code = constraint_str("ALTER TABLE %s DROP CONSTRAINT %s", [table, constraint_name])
-
- validate_constraint_code = String.new(command_str(:validate_check_constraint, [table, {name: constraint_name}]))
-
+ add_args = [table, "#{quote_column_if_needed(column)} IS NOT NULL", {name: constraint_name, validate: false}]
+ validate_args = [table, {name: constraint_name}]
change_args = [table, column, null]
+ remove_args = [table, {name: constraint_name}]
- validate_constraint_code << "\n #{command_str(:change_column_null, change_args)}"
- validate_constraint_code << "\n #{command_str(:remove_check_constraint, [table, {name: constraint_name}])}"
-
if StrongMigrations.safe_by_default
- safe_change_column_null(add_code, validate_code, change_args, remove_code, default)
+ safe_change_column_null(add_args, validate_args, change_args, remove_args, default, constraints)
throw :safe
end
- add_constraint_code = command_str(:add_check_constraint, [table, "#{quote_column_if_needed(column)} IS NOT NULL", {name: constraint_name, validate: false}])
+ add_constraint_code = command_str(:add_check_constraint, add_args)
+ up_code = String.new(command_str(:validate_check_constraint, validate_args))
+ up_code << "\n #{command_str(:change_column_null, change_args)}"
+ up_code << "\n #{command_str(:remove_check_constraint, remove_args)}"
down_code = "#{add_constraint_code}\n #{command_str(:change_column_null, [table, column, true])}"
- validate_constraint_code = "def up\n #{validate_constraint_code}\n end\n\n def down\n #{down_code}\n end"
+ validate_constraint_code = "def up\n #{up_code}\n end\n\n def down\n #{down_code}\n end"
raise_error :change_column_null_postgresql,
add_constraint_code: add_constraint_code,
validate_constraint_code: validate_constraint_code
end
@@ -300,33 +298,32 @@
def check_remove_column(method, *args)
columns =
case method
when :remove_timestamps
- ["created_at", "updated_at"]
+ [:created_at, :updated_at]
when :remove_column
- [args[1].to_s]
+ [args[1]]
when :remove_columns
- # Active Record 6.1+ supports options
if args.last.is_a?(Hash)
- args[1..-2].map(&:to_s)
+ args[1..-2]
else
- args[1..-1].map(&:to_s)
+ args[1..-1]
end
else
options = args[2] || {}
reference = args[1]
cols = []
- cols << "#{reference}_type" if options[:polymorphic]
- cols << "#{reference}_id"
+ cols << "#{reference}_type".to_sym if options[:polymorphic]
+ cols << "#{reference}_id".to_sym
cols
end
- code = "self.ignored_columns += #{columns.inspect}"
+ code = "self.ignored_columns += #{columns.map(&:to_s).inspect}"
raise_error :remove_column,
- model: args[0].to_s.classify,
+ model: model_name(args[0]),
code: code,
command: command_str(method, args),
column_suffix: columns.size > 1 ? "s" : ""
end
@@ -390,11 +387,11 @@
message = StrongMigrations.error_messages[message_key] || "Missing message"
message = message + append if append
vars[:migration_name] = @migration.class.name
- vars[:migration_suffix] = "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
+ vars[:migration_suffix] = migration_suffix
vars[:base_model] = "ApplicationRecord"
# escape % not followed by {
message = message.gsub(/%(?!{)/, "%%") % vars if message.include?("%")
@migration.stop!(message, header: header || "Dangerous operation detected")
@@ -431,11 +428,11 @@
"#{command} #{str_args.join(", ")}"
end
def backfill_code(table, column, default, function = false)
- model = table.to_s.classify
+ model = model_name(table)
if function
# update_all(column: Arel.sql(default)) also works in newer versions of Active Record
update_expr = "#{quote_column_if_needed(column)} = #{default}"
"#{model}.unscoped.in_batches do |relation| \n relation.where(#{column}: nil).update_all(#{update_expr.inspect})\n sleep(0.01)\n end"
else
@@ -453,8 +450,16 @@
@new_tables.include?(table.to_s)
end
def new_column?(table, column)
new_table?(table) || @new_columns.include?([table.to_s, column.to_s])
+ end
+
+ def migration_suffix
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
+ end
+
+ def model_name(table)
+ table.to_s.classify
end
end
end