Created
October 4, 2018 23:52
-
-
Save ridiculous/e2753fc217af19cab0a2f3edac6d5ce7 to your computer and use it in GitHub Desktop.
Find discrepancies between Rails schema.rb and the actual database
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FakeSchema | |
attr_reader :defs, :diff | |
def self.define(*, &block) | |
$schema = new | |
$schema.instance_eval(&block) | |
end | |
def initialize | |
@defs = {} | |
end | |
def create_table(name, options, &block) | |
@defs[name] = {} | |
yield table = FakeTable.new(options) | |
@defs[name][:columns] = table.columns | |
nil | |
end | |
def add_index(table_name, fields, options) | |
@defs[table_name][:indexes] ||= [] | |
@defs[table_name][:indexes] << options.fetch(:name) | |
nil | |
end | |
def compare | |
@diff = Hash.new { |me, key| me[key] = HashArray.new } | |
@defs.each do |table, options| | |
db_cols = db.select_values("SHOW FIELDS FROM #{table}") | |
if db_cols.sort != options[:columns].sort | |
@diff[table][:columns] = db_cols - options[:columns] | |
@diff[table][:columns] |= options[:columns] - db_cols | |
end | |
Array(options[:indexes]).each do |index| | |
if db.select_values("SHOW KEYS FROM #{table} WHERE key_name = '#{index}'").blank? | |
@diff[table][:indexes] << index | |
end | |
end | |
end | |
@diff.empty? | |
end | |
def db | |
@db ||= ActiveRecord::Base.connection | |
end | |
class FakeTable | |
attr_reader :columns | |
def initialize(options) | |
@columns = [] | |
@columns << 'id' if options[:id] != false | |
end | |
def method_missing(name, *args, &block) | |
@columns << args.first | |
end | |
end | |
end | |
ActiveRecord::Schema = FakeSchema | |
require Rails.root.join('db/schema') | |
$schema.compare |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment