Class: Exwiw::SchemaGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/exwiw/schema_generator.rb

Constant Summary collapse

ACTIVE_STORAGE_VARIANT_RECORDS_TABLE =

ActiveStorage tracks generated image variants in this table. Its rows are derivative and regenerable — ActiveStorage lazily (re)creates a variant the next time it is requested — so there is little value in exporting them. More importantly, the table has no belongs_to path to any dump target, which would land it in QueryAstBuilder’s “no relation -> dump all” branch, while its ‘blob_id` references active_storage_blobs, which the reverse “referenced_by” extraction narrows to only the attachment-referenced blobs. A full variant_records dump can therefore reference blobs that were never exported (a foreign-key violation on import). So the table is emitted with `ignore: true` (data extraction skipped) and excluded as a polymorphic `record` target so the non-ignored attachments table carries no dangling belongs_to to it.

"active_storage_variant_records"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(models:, output_dir:) ⇒ SchemaGenerator

Returns a new instance of SchemaGenerator.



27
28
29
30
# File 'lib/exwiw/schema_generator.rb', line 27

def initialize(models:, output_dir:)
  @models = models
  @output_dir = output_dir
end

Class Method Details

.from_rails_application(output_dir:) ⇒ Object



22
23
24
25
# File 'lib/exwiw/schema_generator.rb', line 22

def self.from_rails_application(output_dir:)
  Rails.application.eager_load!
  new(models: ActiveRecord::Base.descendants, output_dir: output_dir)
end

Instance Method Details

#build_table_groupsObject

Returns a Hash keyed by the database name.

  • Single-database setup: the only key is ‘nil`, signalling that the table configs should be written flat into `output_dir` (backwards compatible).

  • Multi-database setup (Rails ‘connects_to`): one key per database (`connection_db_config.name`, e.g. “primary” / “analytics”), each mapping to that database’s table configs. They are written into ‘output_dir/<db_name>/`.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/exwiw/schema_generator.rb', line 46

def build_table_groups
  models = concrete_models
  grouped = models.group_by { |model| database_name_for(model) }

  if grouped.size <= 1
    conn = models.empty? ? ActiveRecord::Base.connection : models.first.connection
    return { nil => build_tables_for(models, conn) }
  end

  grouped.each_with_object({}) do |(db_name, group_models), result|
    conn = group_models.first.connection
    result[db_name] = build_tables_for(group_models, conn)
  end
end

#build_tablesObject

Backwards-compatible flat list of all table configs. Only meaningful for a single-database setup; for multi-database setups prefer ‘#build_table_groups` so the database association is preserved.



64
65
66
# File 'lib/exwiw/schema_generator.rb', line 64

def build_tables
  build_table_groups.values.flatten
end

#generate!Object



32
33
34
35
36
# File 'lib/exwiw/schema_generator.rb', line 32

def generate!
  groups = build_table_groups
  write_groups(groups)
  groups
end

#write_files(dir, tables) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/exwiw/schema_generator.rb', line 75

def write_files(dir, tables)
  FileUtils.mkdir_p(dir)

  tables.each do |table|
    path = File.join(dir, "#{table.name}.json")
    config_to_write =
      if File.exist?(path)
        TableConfig.from(JSON.parse(File.read(path))).merge(table)
      else
        table
      end
    File.write(path, JSON.pretty_generate(config_to_write.to_hash) + "\n")
  end
end

#write_groups(groups) ⇒ Object



68
69
70
71
72
73
# File 'lib/exwiw/schema_generator.rb', line 68

def write_groups(groups)
  groups.each do |db_name, tables|
    dir = db_name.nil? ? @output_dir : File.join(@output_dir, db_name)
    write_files(dir, tables)
  end
end