Skip to content

Commit 1956971

Browse files
authored
Add annotation hooks for db-specific migration tasks (#686)
Rails 6 adds a new set of migration tasks for multi-database apps. This change makes the annotate_models_migrate hooks aware of them.
1 parent b3aa361 commit 1956971

File tree

4 files changed

+154
-91
lines changed

4 files changed

+154
-91
lines changed

lib/tasks/annotate_models_migrate.rake

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@
44
# Append annotations to Rake tasks for ActiveRecord, so annotate automatically gets
55
# run after doing db:migrate.
66

7-
%w(db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback).each do |task|
7+
migration_tasks = %w(db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback)
8+
if defined?(Rails::Application) && Rails.version.split('.').first.to_i >= 6
9+
require 'active_record'
10+
11+
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
12+
13+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
14+
migration_tasks.concat(%w(db:migrate db:migrate:up db:migrate:down).map { |task| "#{task}:#{spec_name}" })
15+
end
16+
end
17+
18+
migration_tasks.each do |task|
819
Rake::Task[task].enhance do
920
Rake::Task[Rake.application.top_level_tasks.last].enhance do
1021
annotation_options_task = if Rake::Task.task_defined?('app:set_annotation_options')

spec/integration/rails_6.0.2.1/config/application.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ class Application < Rails::Application
2828
# Application configuration can go into files in config/initializers
2929
# -- all .rb files in that directory are automatically loaded after loading
3030
# the framework and any gems in your application.
31+
self.paths['config/database'] = 'config/multi-database.yml' if ENV['MULTI_DB']
3132
end
3233
end
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# SQLite. Versions 3.8.0 and up are supported.
2+
# gem install sqlite3
3+
#
4+
# Ensure the SQLite 3 gem is defined in your Gemfile
5+
# gem 'sqlite3'
6+
#
7+
default: &default
8+
adapter: sqlite3
9+
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10+
timeout: 5000
11+
12+
development:
13+
primary:
14+
<<: *default
15+
database: db/development.sqlite3
16+
secondary:
17+
<<: *default
18+
database: db/development-secondary.sqlite3
19+
20+
# Warning: The database defined as "test" will be erased and
21+
# re-generated from your development database when you run "rake".
22+
# Do not set this db to the same as development or production.
23+
test:
24+
primary:
25+
<<: *default
26+
database: db/test.sqlite3
27+
secondary:
28+
<<: *default
29+
database: db/test-secondary.sqlite3
30+
31+
production:
32+
primary:
33+
<<: *default
34+
database: db/production.sqlite3
35+
secondary:
36+
<<: *default
37+
database: db/production-secondary.sqlite3

spec/integration/rails_6.0.2.1_spec.rb

Lines changed: 104 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,69 @@
99
::RAILS_6_0_APP_PATH = File.expand_path(RAILS_6_0_APP_NAME, __dir__).freeze
1010

1111
let!(:git) { Git.open(RAILS_6_0_PROJECT_PATH) }
12+
let(:task_model) do
13+
patch = <<~PATCH
14+
+# == Schema Information
15+
+#
16+
+# Table name: tasks
17+
+#
18+
+# id :integer not null, primary key
19+
+# content :string
20+
+# count :integer default(0)
21+
+# status :boolean default(FALSE)
22+
+# created_at :datetime not null
23+
+# updated_at :datetime not null
24+
+#
25+
PATCH
26+
27+
path = 'app/models/task.rb'
28+
{
29+
path: include(path),
30+
patch: include(patch)
31+
}
32+
end
33+
let(:task_test) do
34+
patch = <<~PATCH
35+
+# == Schema Information
36+
+#
37+
+# Table name: tasks
38+
+#
39+
+# id :integer not null, primary key
40+
+# content :string
41+
+# count :integer default(0)
42+
+# status :boolean default(FALSE)
43+
+# created_at :datetime not null
44+
+# updated_at :datetime not null
45+
+#
46+
PATCH
47+
48+
path = 'test/models/task_test.rb'
49+
{
50+
path: include(path),
51+
patch: include(patch)
52+
}
53+
end
54+
let(:task_fixture) do
55+
patch = <<~PATCH
56+
+# == Schema Information
57+
+#
58+
+# Table name: tasks
59+
+#
60+
+# id :integer not null, primary key
61+
+# content :string
62+
+# count :integer default(0)
63+
+# status :boolean default(FALSE)
64+
+# created_at :datetime not null
65+
+# updated_at :datetime not null
66+
+#
67+
PATCH
68+
69+
path = 'test/fixtures/tasks.yml'
70+
{
71+
path: include(path),
72+
patch: include(patch)
73+
}
74+
end
1275

1376
before(:all) do
1477
Bundler.with_clean_env do
@@ -19,91 +82,31 @@
1982
end
2083
end
2184

85+
around(:each) do |example|
86+
Bundler.with_clean_env do
87+
Dir.chdir RAILS_6_0_APP_PATH do
88+
example.run
89+
end
90+
end
91+
end
92+
2293
after(:each) do
2394
git.reset_hard
2495
end
2596

2697
describe 'annotate --models' do
2798
let(:command) { 'bundle exec annotate --models' }
2899

29-
let(:task_model) do
30-
patch = <<~PATCH
31-
+# == Schema Information
32-
+#
33-
+# Table name: tasks
34-
+#
35-
+# id :integer not null, primary key
36-
+# content :string
37-
+# count :integer default(0)
38-
+# status :boolean default(FALSE)
39-
+# created_at :datetime not null
40-
+# updated_at :datetime not null
41-
+#
42-
PATCH
43-
44-
path = 'app/models/task.rb'
45-
{
46-
path: include(path),
47-
patch: include(patch)
48-
}
49-
end
50-
let(:task_test) do
51-
patch = <<~PATCH
52-
+# == Schema Information
53-
+#
54-
+# Table name: tasks
55-
+#
56-
+# id :integer not null, primary key
57-
+# content :string
58-
+# count :integer default(0)
59-
+# status :boolean default(FALSE)
60-
+# created_at :datetime not null
61-
+# updated_at :datetime not null
62-
+#
63-
PATCH
64-
65-
path = 'test/models/task_test.rb'
66-
{
67-
path: include(path),
68-
patch: include(patch)
69-
}
70-
end
71-
let(:task_fixture) do
72-
patch = <<~PATCH
73-
+# == Schema Information
74-
+#
75-
+# Table name: tasks
76-
+#
77-
+# id :integer not null, primary key
78-
+# content :string
79-
+# count :integer default(0)
80-
+# status :boolean default(FALSE)
81-
+# created_at :datetime not null
82-
+# updated_at :datetime not null
83-
+#
84-
PATCH
85-
86-
path = 'test/fixtures/tasks.yml'
87-
{
88-
path: include(path),
89-
patch: include(patch)
90-
}
91-
end
92-
93100
it 'annotate models' do
94-
Bundler.with_clean_env do
95-
Dir.chdir RAILS_6_0_APP_PATH do
96-
expect(git.diff.any?).to be_falsy
97-
98-
puts `#{command}`
99-
100-
expect(git.diff.entries).to contain_exactly(
101-
an_object_having_attributes(task_model),
102-
an_object_having_attributes(task_test),
103-
an_object_having_attributes(task_fixture)
104-
)
105-
end
106-
end
101+
expect(git.diff.any?).to be_falsy
102+
103+
puts `#{command}`
104+
105+
expect(git.diff.entries).to contain_exactly(
106+
an_object_having_attributes(task_model),
107+
an_object_having_attributes(task_test),
108+
an_object_having_attributes(task_fixture)
109+
)
107110
end
108111
end
109112

@@ -156,30 +159,41 @@
156159
end
157160

158161
it 'annotate routes.rb' do
159-
Bundler.with_clean_env do
160-
Dir.chdir RAILS_6_0_APP_PATH do
161-
expect(git.diff.any?).to be_falsy
162+
expect(git.diff.any?).to be_falsy
162163

163-
puts `#{command}`
164+
puts `#{command}`
164165

165-
expect(git.diff.entries).to contain_exactly(an_object_having_attributes(task_routes))
166-
end
167-
end
166+
expect(git.diff.entries).to contain_exactly(an_object_having_attributes(task_routes))
168167
end
169168
end
170169

171170
describe 'rails g annotate:install' do
172171
let(:command) { 'bin/rails g annotate:install' }
173172
let(:rake_file_path) { 'lib/tasks/auto_annotate_models.rake' }
173+
let(:full_path) { File.expand_path(rake_file_path) }
174+
175+
after(:each) do
176+
File.delete(full_path)
177+
end
174178

175179
it 'generates the rake file' do
176-
Bundler.with_clean_env do
177-
Dir.chdir RAILS_6_0_APP_PATH do
178-
full_path = File.expand_path(rake_file_path)
179-
expect { `#{command}` }.to change { File.exist?(rake_file_path) }.from(false).to(true)
180+
expect { `#{command}` }.to change { File.exist?(rake_file_path) }.from(false).to(true)
181+
end
182+
183+
context 'with multi-db environment' do
184+
let(:migrate_command) { 'bin/rails db:migrate:primary' }
185+
186+
it 'hooks database-specific commands and annotates models' do
187+
expect(git.diff.any?).to be_falsy
188+
189+
system({ 'MULTI_DB' => 'true' }, command)
190+
system({ 'MULTI_DB' => 'true' }, migrate_command)
180191

181-
File.delete(full_path)
182-
end
192+
expect(git.diff.entries).to contain_exactly(
193+
an_object_having_attributes(task_model),
194+
an_object_having_attributes(task_test),
195+
an_object_having_attributes(task_fixture)
196+
)
183197
end
184198
end
185199
end

0 commit comments

Comments
 (0)