Per Consider sorting of hashes for schema_cache.yml · Issue #42717 · rails/rails · GitHub, I was told to get some feedback here.
Should the db/schema_cache.yml
be sorted?
Steps to reproduce
- Two developers have migrations run in different orders
- Each developer runs
rake db:schema:cache:dump
Expected behavior
Contents of the schema_cache.yml
produced on 2 separate machines/databases for the same exact schema (although column orders might be different) will be exactly the same.
Actual behavior
Contents of the schema_cache.yml
produced on 2 separate machines/databases for the same exact schema (although column orders might be different)will vary by sort order only.
Monkey Patch to Sort
class ActiveRecord::ConnectionAdapters::SchemaCache
def sort_by_hash_of_array_of_named_objects(hash)
hash.transform_values { |v| v.sort_by(&:name) }.sort.to_h
end
def sort_all!
# rubocop:disable Rails/Output
puts 'MONKEY PATCH (schema_cache_extension.rb): Sorting @colums, @columns_hash, @primary_keys, @data_sources, @indexes of ActiveRecord::ConnectionAdapters::SchemaCache'
# rubocop:enable Rails/Output
@columns = sort_by_hash_of_array_of_named_objects(@columns)
# This is a Hash of Hashes
@columns_hash = @columns_hash.transform_values { |v| v.sort.to_h }.sort.to_h
@primary_keys = @primary_keys.sort.to_h
@data_sources = @data_sources.sort.to_h
@indexes = sort_by_hash_of_array_of_named_objects(@indexes)
end
end
module ActiveRecord::Tasks::DatabaseTasks
def dump_schema_cache(conn, filename)
# rubocop:disable Rails/Output
binding.pry
puts 'MONKEY PATCH (schema_cache_extension.rb): ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache adjusted to sort'
# rubocop:enable Rails/Output
conn.schema_cache.clear!
conn.data_sources.each { |table| conn.schema_cache.add(table) }
conn.schema_cache.sort_all!
# This is the line that skipped the compression
# open(filename, 'wb') { |f| f.write(YAML.dump(conn.schema_cache)) }
# correct line
conn.schema_cache.dump_to(filename)
end
end
On a related note, the GitHub - jakeonrails/fix-db-schema-conflicts does something similar for db/schema.rb
files.