Skip to content

Commit 57f7901

Browse files
authored
feat: Add database name to annotations in multi-DB environments (#272)
## Problem In a multi-database environment, it can be confusing to determine which database a model's table belongs to just by looking at the schema annotations. This can lead to developers mistakenly thinking a table is missing when it simply resides in a different database. ## Solution This commit introduces a new line in the schema information block that conditionally displays the database name. - In multi-database environments, the database name is now shown to provide clarity: ``` # == Schema Information # # Table name: tasks # Database name: second_database # # ... ``` - In single-database environments, the database name is not displayed to avoid unnecessary clutter. Refs #254 I really enjoy contributing to this gem and hope to contribute even more. Thank you for always maintaining it! 👍
1 parent 0c6861f commit 57f7901

File tree

6 files changed

+85
-8
lines changed

6 files changed

+85
-8
lines changed

lib/annotate_rb/model_annotator/annotation/annotation_builder.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module ModelAnnotator
55
module Annotation
66
class AnnotationBuilder
77
class Annotation < Components::Base
8-
attr_reader :version, :table_name, :table_comment, :max_size
8+
attr_reader :version, :table_name, :table_comment, :max_size, :database_name
99

1010
def initialize(options, **input)
1111
@options = options
@@ -15,12 +15,13 @@ def initialize(options, **input)
1515
@table_comment = input[:table_comment]
1616
@max_size = input[:max_size]
1717
@model = input[:model]
18+
@database_name = input[:database_name]
1819
end
1920

2021
def body
2122
[
2223
MainHeader.new(version, @options[:include_version]),
23-
SchemaHeader.new(table_name, table_comment, @options),
24+
SchemaHeader.new(table_name, table_comment, database_name, @options),
2425
MarkdownHeader.new(max_size),
2526
*columns,
2627
IndexAnnotation::AnnotationBuilder.new(@model, @options).build,
@@ -63,10 +64,21 @@ def build
6364
table_name = @model.table_name
6465
table_comment = @model.connection.try(:table_comment, @model.table_name)
6566
max_size = @model.max_schema_info_width
67+
database_name = @model.database_name if multi_db_environment?
6668

6769
_annotation = Annotation.new(@options,
6870
version: version, table_name: table_name, table_comment: table_comment,
69-
max_size: max_size, model: @model).build
71+
max_size: max_size, model: @model, database_name: database_name).build
72+
end
73+
74+
private
75+
76+
def multi_db_environment?
77+
if defined?(::Rails) && ::Rails.env
78+
ActiveRecord::Base.configurations.configs_for(env_name: ::Rails.env).size > 1
79+
else
80+
false
81+
end
7082
end
7183
end
7284
end

lib/annotate_rb/model_annotator/annotation/schema_header.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,38 @@ def to_markdown
2020
end
2121
end
2222

23-
attr_reader :table_name, :table_comment
23+
class DatabaseName < Components::Base
24+
attr_reader :name
25+
26+
def initialize(name)
27+
@name = name
28+
end
29+
30+
def to_default
31+
"# Database name: #{name}"
32+
end
33+
34+
def to_markdown
35+
"# Database name: `#{name}`"
36+
end
37+
end
38+
39+
attr_reader :table_name, :table_comment, :database_name
2440

25-
def initialize(table_name, table_comment, options)
41+
def initialize(table_name, table_comment, database_name, options)
2642
@table_name = table_name
2743
@table_comment = table_comment
44+
@database_name = database_name
2845
@options = options
2946
end
3047

3148
def body
3249
[
3350
Components::BlankCommentLine.new,
3451
TableName.new(name),
52+
(DatabaseName.new(database_name) if database_name),
3553
Components::BlankCommentLine.new
36-
]
54+
].compact
3755
end
3856

3957
def to_default

lib/annotate_rb/model_annotator/model_wrapper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def connection
3838
@klass.connection
3939
end
4040

41+
def database_name
42+
connection.pool.db_config.name
43+
end
44+
4145
# Returns the unmodified model columns
4246
def raw_columns
4347
@raw_columns ||= @klass.columns

spec/integration/annotate_models_in_multi_db_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,14 @@
2424
# Ensure "Model files unchanged." is included in the output
2525
expect(second_run_output).to include("Model files unchanged.")
2626
end
27+
28+
it "includes the database name in the annotation for secondary models" do
29+
reset_database
30+
run_migrations
31+
32+
run_command_and_stop("bundle exec annotaterb models", fail_on_error: true, exit_timeout: command_timeout_seconds)
33+
34+
content = read_file(dummyapp_model("secondary/test_default.rb"))
35+
expect(content).to include("# Database name: secondary")
36+
end
2737
end

spec/integration/annotate_single_file_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
expect(last_command_started).to be_successfully_executed
3131
expect(annotated_test_default).to eq(expected_test_default)
32+
expect(annotated_test_default).not_to include("# Database name:")
3233
expect(annotated_test_null_false).not_to eq(expected_test_null_false)
3334
end
3435
end

spec/lib/annotate_rb/model_annotator/annotation/schema_header_spec.rb

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
RSpec.describe AnnotateRb::ModelAnnotator::Annotation::SchemaHeader do
44
describe "#to_default" do
5-
subject { described_class.new(table_name, table_comment, options).to_default }
5+
subject { described_class.new(table_name, table_comment, database_name, options).to_default }
66

77
let(:table_name) { "users" }
88
let(:table_comment) {}
9+
let(:database_name) {}
910
let :options do
1011
AnnotateRb::Options.new({})
1112
end
@@ -20,6 +21,21 @@
2021

2122
it { is_expected.to eq(expected_header) }
2223

24+
context "with database_name" do
25+
let(:database_name) { "secondary" }
26+
27+
let(:expected_header) do
28+
<<~HEADER.strip
29+
#
30+
# Table name: users
31+
# Database name: secondary
32+
#
33+
HEADER
34+
end
35+
36+
it { is_expected.to eq(expected_header) }
37+
end
38+
2339
context "with `with_comment: true`" do
2440
context "with `with_table_comments: true` and table has comments" do
2541
let :options do
@@ -126,10 +142,11 @@
126142
end
127143

128144
describe "#to_markdown" do
129-
subject { described_class.new(table_name, table_comment, options).to_markdown }
145+
subject { described_class.new(table_name, table_comment, database_name, options).to_markdown }
130146

131147
let(:table_name) { "users" }
132148
let(:table_comment) {}
149+
let(:database_name) {}
133150
let :options do
134151
AnnotateRb::Options.new({})
135152
end
@@ -143,5 +160,20 @@
143160
end
144161

145162
it { is_expected.to eq(expected_header) }
163+
164+
context "with database_name" do
165+
let(:database_name) { "secondary" }
166+
167+
let(:expected_header) do
168+
<<~HEADER.strip
169+
#
170+
# Table name: `users`
171+
# Database name: `secondary`
172+
#
173+
HEADER
174+
end
175+
176+
it { is_expected.to eq(expected_header) }
177+
end
146178
end
147179
end

0 commit comments

Comments
 (0)