migration_data 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -19
- data/lib/migration_data/active_record/migration.rb +14 -3
- data/lib/migration_data/config.rb +2 -1
- data/lib/migration_data/version.rb +1 -1
- data/test/migration_test.rb +45 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e38d42f09ec6e1f9ad7d4a5f2ed30b09620d96cacf0b0e350e075e48a903c01
|
4
|
+
data.tar.gz: 8b89215996f8767f76d3bbcb00cf877df9926081a5002eb08b02264659a381db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3946bc0b85d77e9371343b1e88c3cc5184fbb060ccbbbba7db76b2ed3cfa0c94025244ed9298029cb2cd928b39b2933f86c0177a9d458c65677a681e457a7afa
|
7
|
+
data.tar.gz: c5c064d32d9852fd5bd66b36e74a5816d773f9bbb15e7f3985304f9f11a5215e66a441478840bc110da8a08a7d540c3541558a20658a8927e2b05b0c3c202cf3
|
data/README.md
CHANGED
@@ -10,9 +10,9 @@ some techniques which help to avoid these pitfalls. For example, define model
|
|
10
10
|
classes in the migrations or write raw SQL. But they don't help in 100% of all cases.
|
11
11
|
This gem promises to solve this problem in a simple way.
|
12
12
|
|
13
|
-
|
13
|
+
In short, this gem promotes writing the code migrates data in separate methods of a schema migration. That separates concerns and allows writing tests for these methods. Also, they optionally can be skipped.
|
14
14
|
|
15
|
-
If
|
15
|
+
If it's still not clear what this gem is for please check out [this blog post](http://railsguides.net/2014/01/30/change-data-in-migrations-like-a-boss/).
|
16
16
|
|
17
17
|
## Installation
|
18
18
|
|
@@ -30,7 +30,7 @@ Or install it yourself as:
|
|
30
30
|
|
31
31
|
## Usage
|
32
32
|
|
33
|
-
In your migration define a
|
33
|
+
In your migration define a `#data` method:
|
34
34
|
|
35
35
|
```ruby
|
36
36
|
class CreateUsers < ActiveRecord::Migration
|
@@ -48,11 +48,41 @@ class CreateUsers < ActiveRecord::Migration
|
|
48
48
|
end
|
49
49
|
```
|
50
50
|
|
51
|
-
|
52
|
-
|
51
|
+
Now when migrations run with `rake db:migrate` command the `#data` method is executed right after the standard `#change` or `#up` method.
|
52
|
+
|
53
|
+
When migrations roll back with `rake db:rollback` command the `#rollback` is executed right after the standard `#change` or `#down` method.
|
54
|
+
|
55
|
+
It might appear that a data migration should run *before* the standard `#change`, `#up`, and `#down` methods. Define `#data_before` and `#rollback_before` methods for "up" and "down" directions correspondingly. There are also `#data_after` and `#rollback_after` methods for symmetry in that case, but basically they play the same role as `#data` and `#rollback` methods.
|
56
|
+
|
57
|
+
All these methods can be defined in one migration. They are executed in the following order when migration is run on up:
|
58
|
+
- `#data_before`
|
59
|
+
- `#change/up`
|
60
|
+
- `#data`
|
61
|
+
- `#data_after`
|
62
|
+
|
63
|
+
and on down:
|
64
|
+
|
65
|
+
- `#rollback_before`
|
66
|
+
- `#change/down`
|
67
|
+
- `#rollback`
|
68
|
+
- `#rollback_after`.
|
53
69
|
|
54
70
|
> Note: in some circumstances, the `reset_column_information` method should be called on a model which table is changed in the migration. Especially when you are certain that there should be present some column for a model but it's absent for some reason. Read more about this in the [official Rails docs](http://guides.rubyonrails.org/v4.1/migrations.html#using-models-in-your-migrations).
|
55
71
|
|
72
|
+
## Skipping data migrations execution
|
73
|
+
|
74
|
+
At some point, one might realize that data migrations should not run on particular environments, e.g. `test`.
|
75
|
+
|
76
|
+
On performing migrations in `test` environment, a data migration might try to add the same data that has already been added by seeds. In that case, migrations might fail with a duplication error.
|
77
|
+
|
78
|
+
Use `MigrationData.config.skip = true` to skip data migrations execution. One might put this code in an initializer, e.g. `config/initializers/migration_data.rb`:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
if Rails.env.test?
|
82
|
+
MigrationData.config.skip = true
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
56
86
|
## Testing migrations
|
57
87
|
|
58
88
|
To keep your migrations working don't forget to write tests for them. It's preferably to put the tests for migrations into `spec/db/migrations` folder, but actually it's up to you. Possible `RSpec` test (`spec/db/migrations/create_user.rb`) for the migration looks like this:
|
@@ -83,20 +113,6 @@ end
|
|
83
113
|
|
84
114
|
The helper to load migrations `require_migration` is defined in the `migration_data/testing`. So you should to require it to have access to this convenient require extension.
|
85
115
|
|
86
|
-
## Skipping data migrations execution
|
87
|
-
|
88
|
-
At some point, one might realize that data migrations should not run on particular environments, e.g. `test`.
|
89
|
-
|
90
|
-
On performing migrations in `test` environment, a data migration might try to add the same data that has already been added by seeds. In that case, migrations might fail with a duplication error.
|
91
|
-
|
92
|
-
Use `MigrationData.config.skip = true` to skip data migrations execution. One might put this code in an initializer, e.g. `config/initializers/migration_data.rb`:
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
if Rails.env.test?
|
96
|
-
MigrationData.config.skip = true
|
97
|
-
end
|
98
|
-
```
|
99
|
-
|
100
116
|
## Contributing
|
101
117
|
|
102
118
|
1. Fork it ( http://github.com/ka8725/migration_data/fork )
|
@@ -14,15 +14,26 @@ module MigrationData
|
|
14
14
|
def self.included(base)
|
15
15
|
base.class_eval do
|
16
16
|
def exec_migration_with_data(conn, direction)
|
17
|
+
data_before if should_run?(direction == :up, :data_before)
|
18
|
+
rollback_before if should_run?(direction == :down, :rollback_before)
|
19
|
+
|
17
20
|
origin_exec_migration(conn, direction)
|
18
21
|
::ActiveRecord::Base.connection.schema_cache.clear!
|
19
|
-
|
20
|
-
data if direction == :up
|
21
|
-
|
22
|
+
|
23
|
+
data if should_run?(direction == :up, :data)
|
24
|
+
data_after if should_run?(direction == :up, :data_after)
|
25
|
+
rollback if should_run?(direction == :down, :rollback)
|
26
|
+
rollback_after if should_run?(direction == :down, :rollback_after)
|
22
27
|
end
|
23
28
|
|
24
29
|
alias origin_exec_migration exec_migration
|
25
30
|
alias exec_migration exec_migration_with_data
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def should_run?(is_ok_direction, method_name)
|
35
|
+
is_ok_direction && !MigrationData.config.skip && respond_to?(method_name)
|
36
|
+
end
|
26
37
|
end
|
27
38
|
end
|
28
39
|
end
|
data/test/migration_test.rb
CHANGED
@@ -1,15 +1,36 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class MyMigration < ActiveRecord::Migration[4.2]
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :migrated_data_before,
|
5
|
+
:migrated_data,
|
6
|
+
:migrated_data_after,
|
7
|
+
:rolled_back_data_before,
|
8
|
+
:rolled_back_data,
|
9
|
+
:rolled_back_data_after
|
10
|
+
|
11
|
+
def data_before
|
12
|
+
@migrated_data_before = true
|
13
|
+
end
|
5
14
|
|
6
15
|
def data
|
7
16
|
@migrated_data = true
|
8
17
|
end
|
9
18
|
|
19
|
+
def data_after
|
20
|
+
@migrated_data_after = true
|
21
|
+
end
|
22
|
+
|
23
|
+
def rollback_before
|
24
|
+
@rolled_back_data_before = true
|
25
|
+
end
|
26
|
+
|
10
27
|
def rollback
|
11
28
|
@rolled_back_data = true
|
12
29
|
end
|
30
|
+
|
31
|
+
def rollback_after
|
32
|
+
@rolled_back_data_after = true
|
33
|
+
end
|
13
34
|
end
|
14
35
|
|
15
36
|
describe MyMigration do
|
@@ -20,42 +41,50 @@ describe MyMigration do
|
|
20
41
|
describe '#migrate' do
|
21
42
|
it 'runs #data on up direction' do
|
22
43
|
@migration.migrate(:up)
|
44
|
+
assert @migration.migrated_data_before
|
23
45
|
assert @migration.migrated_data
|
46
|
+
assert @migration.migrated_data_after
|
24
47
|
end
|
25
48
|
|
26
49
|
it "doesn't run #data on down direction" do
|
27
50
|
@migration.migrate(:down)
|
51
|
+
assert_nil @migration.migrated_data_before
|
28
52
|
assert_nil @migration.migrated_data
|
53
|
+
assert_nil @migration.migrated_data_after
|
29
54
|
end
|
30
55
|
|
31
56
|
it 'runs #rollback on down direction' do
|
32
57
|
@migration.migrate(:down)
|
58
|
+
assert @migration.rolled_back_data_before
|
33
59
|
assert @migration.rolled_back_data
|
60
|
+
assert @migration.rolled_back_data_after
|
34
61
|
end
|
35
62
|
|
36
63
|
it "doesn't run #rollback on up direction" do
|
37
64
|
@migration.migrate(:up)
|
65
|
+
assert_nil @migration.rolled_back_data_before
|
38
66
|
assert_nil @migration.rolled_back_data
|
67
|
+
assert_nil @migration.rolled_back_data_after
|
39
68
|
end
|
40
|
-
end
|
41
69
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
70
|
+
describe 'when skipping' do
|
71
|
+
before do
|
72
|
+
@old_skip, MigrationData.config.skip = MigrationData.config.skip, true
|
73
|
+
end
|
46
74
|
|
47
|
-
|
48
|
-
|
49
|
-
|
75
|
+
after do
|
76
|
+
MigrationData.config.skip = @old_skip
|
77
|
+
end
|
50
78
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
79
|
+
it "doesn't runs #data" do
|
80
|
+
@migration.migrate(:up)
|
81
|
+
refute @migration.migrated_data
|
82
|
+
end
|
55
83
|
|
56
|
-
|
57
|
-
|
58
|
-
|
84
|
+
it "doesn't runs #rollback" do
|
85
|
+
@migration.migrate(:down)
|
86
|
+
refute @migration.rolled_back_data
|
87
|
+
end
|
59
88
|
end
|
60
89
|
end
|
61
90
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: migration_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Koleshko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|