column_hider 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{README.rdoc → README.md} +50 -37
- data/lib/column_hider/version.rb +1 -1
- data/lib/column_hider.rb +3 -1
- data/test/column_hider_test.rb +1 -1
- data/test/dummy/log/test.log +9 -0
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: badf7c2c991d783e0e4b34b2008ad9e4dc05cc09
|
4
|
+
data.tar.gz: ba10ae1db681ea76972df423cda94c0da7372c3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f49d270c3bf75e4f9feb9923729ea2f3834558dae2808db87b3d042b62437d20d3816e632914fdaf76cc88297efe09213d4f5a1d67594c1c0dd178a432627acb
|
7
|
+
data.tar.gz: 8d1cd306bf2e5886f85dc86fd5c581afd3be6f61edd9170a4d1614f2ab0e23254d73b4b1e1a832aeb114917d9222f6e85fc0791936f26274649a585de0531d80
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,71 +1,84 @@
|
|
1
|
-
|
1
|
+
# ColumnHider
|
2
2
|
|
3
|
-
|
3
|
+
## Procedure for deleting or renaming database columns in Rails applications
|
4
4
|
|
5
|
-
|
5
|
+
### Avoiding downtime, or reliability issues during deploys
|
6
6
|
|
7
|
-
Ian Hall
|
8
|
-
|
7
|
+
Ian Hall, May 2015
|
8
|
+
|
9
|
+
___
|
9
10
|
|
10
|
-
---
|
11
11
|
The process of deleting or renaming columns in a production database has some hidden dangers, more or less severe depending on how long it takes to run different parts of your deployment process.
|
12
12
|
|
13
13
|
This procedure aims to completely avoid these issues. If you can’t afford an deployment outage and want your application to be as close to 100% available as possible, you might like to consider this procedure.
|
14
14
|
|
15
|
-
|
16
|
-
== Renaming columns
|
17
|
-
|
18
|
-
The simple solution to this is: don’t do it! Instead:
|
19
|
-
|
20
|
-
* create a new column with the desired name
|
21
|
-
* migrate all data from the old column to the new column
|
22
|
-
* change all references to the old column name in your code to use the new column name
|
23
|
-
* (optional) use the column-deletion procedure below to remove the old column
|
24
|
-
|
25
|
-
The second step, migrating data from old to new columns, may need to be repeated before the fourth step if there is any gap in time which allows data to be updated between steps two and three.
|
15
|
+
___
|
26
16
|
|
27
|
-
|
28
|
-
|
17
|
+
## Column-deletion procedure
|
18
|
+
### Problem Definition
|
29
19
|
|
30
|
-
When a Rails model is first used in a running Rails application, all the columns in the underlying database table are enumerated. The list of columns is kept in a class instance variable of an <code>ActiveRecord::Attribute::ClassMethods</code> method named
|
20
|
+
When a Rails model is first used in a running Rails application, all the columns in the underlying database table are enumerated. The list of columns is kept in a class instance variable of an <code>ActiveRecord::Attribute::ClassMethods</code> method named `columns`. Once created, this variable persists for the lifetime of the running application.
|
31
21
|
|
32
22
|
Caching the column names this way is a good performance enhancement for the application, but it can lead to problems during or after database changes.
|
33
23
|
|
34
|
-
Without the procedure described below, one would run a migration to physically remove the column-to-be-deleted (
|
24
|
+
Without the procedure described below, one would run a migration to physically remove the column-to-be-deleted (`CTBD`), then deploy a new version of the application, with all references to the `CTBD` removed. After successful deployment, restart the application.
|
35
25
|
|
36
26
|
<b>The danger period is the interval between the migration completing and the application restarting.</b>
|
37
27
|
|
38
28
|
Even though this interval may be relatively short - perhaps only a minute or two - if it’s possible that the running application will access the table that you’ve changed with the migration, then you’ll run into a problem.
|
39
29
|
|
40
|
-
|
30
|
+
### Solution
|
31
|
+
|
32
|
+
The solution to this problem lies in overriding the `ActiveRecord` columns method described above.
|
41
33
|
|
42
|
-
|
34
|
+
* Step One
|
43
35
|
|
44
|
-
|
36
|
+
Add the `column_hider` gem to your Gemfile and run `bundle install`.
|
45
37
|
|
46
|
-
In the model for your application which contains the
|
38
|
+
In the model for your application which contains the `CTBD`, add these two lines:
|
47
39
|
|
48
|
-
|
49
|
-
|
40
|
+
```ruby
|
41
|
+
extend ColumnHider::ActiveRecordAttributes
|
42
|
+
column_hider_columns :column_one
|
43
|
+
```
|
50
44
|
|
51
|
-
where
|
45
|
+
where `:column_one` is the `CTBD`.
|
52
46
|
|
53
|
-
This logically deletes the column from the application - whenever the application accesses the model, the column will be removed from the list of columns that the application knows about.
|
47
|
+
This logically deletes the column from the application - whenever the application accesses the model, the column will be removed from the list of columns that the application knows about.
|
54
48
|
|
55
|
-
Then go through your application in the normal way and remove all other references to the
|
49
|
+
Then go through your application in the normal way and remove all other references to the `CTBD`.
|
56
50
|
|
57
|
-
|
51
|
+
* Step Two
|
52
|
+
|
53
|
+
Deploy the code changes made in Step One.
|
58
54
|
|
59
|
-
At this point, your application will know nothing about the
|
55
|
+
At this point, your application will know nothing about the `CTBD`.
|
60
56
|
|
61
|
-
|
57
|
+
* Step Three
|
58
|
+
|
59
|
+
Create and deploy a Rails migration to physically remove the `CTBD`.
|
62
60
|
|
63
|
-
|
61
|
+
* Step Four
|
64
62
|
|
65
|
-
|
63
|
+
Remove the two lines from your model that were added in Step One. Deploy this whenever …
|
64
|
+
|
65
|
+
* Step Five
|
66
|
+
|
67
|
+
… and relax!
|
68
|
+
|
69
|
+
## Renaming columns
|
70
|
+
|
71
|
+
The simple solution to this is: don’t do it! Instead:
|
72
|
+
|
73
|
+
* create a new column with the desired name
|
74
|
+
* migrate all data from the old column to the new column
|
75
|
+
* change all references to the old column name in your code to use the new column name
|
76
|
+
* (optional) use the column-deletion procedure above to remove the old column
|
77
|
+
|
78
|
+
The second step, migrating data from old to new columns, may need to be repeated before the fourth step if there is any gap in time which allows data to be updated between steps two and three.
|
66
79
|
|
67
|
-
|
80
|
+
## Conclusion
|
68
81
|
|
69
|
-
This might seem like a long-winded way to go about it, but it
|
82
|
+
This might seem like a long-winded way to go about it, but it will help you avoid any problems in your running application when deleting or renaming columns.
|
70
83
|
|
71
84
|
Your mileage may vary, depending on the usage pattern of your application. If you can afford to take downtime and close down user access during a deployment window, you can safely run a destructive migration followed by an application deploy.
|
data/lib/column_hider/version.rb
CHANGED
data/lib/column_hider.rb
CHANGED
@@ -8,7 +8,7 @@ module ColumnHider
|
|
8
8
|
# ` extend ColumnHider`
|
9
9
|
# ` column_hider_columns :column_one, :column_two, ...`
|
10
10
|
#
|
11
|
-
|
11
|
+
module ActiveRecordAttributes
|
12
12
|
def column_hider_columns(*cols)
|
13
13
|
@column_hider_columns = []
|
14
14
|
cols.each do |col|
|
@@ -20,4 +20,6 @@ module ColumnHider
|
|
20
20
|
@column_hider_columns ||= [] # just in case the model includes the line " extend ColumnHider", but doesn't call column_hider_columns
|
21
21
|
super.reject { |col| @column_hider_columns.include?(col.name) }
|
22
22
|
end
|
23
|
+
end
|
24
|
+
|
23
25
|
end
|
data/test/column_hider_test.rb
CHANGED
data/test/dummy/log/test.log
CHANGED
@@ -85,3 +85,12 @@
|
|
85
85
|
[1m[36m (0.2ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
86
86
|
[1m[35m (0.1ms)[0m CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar)
|
87
87
|
[1m[36m (0.2ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
88
|
+
[1m[36m (0.2ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
89
|
+
[1m[35m (0.2ms)[0m CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar)
|
90
|
+
[1m[36m (0.1ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
91
|
+
[1m[36m (0.3ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
92
|
+
[1m[35m (0.1ms)[0m CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar)
|
93
|
+
[1m[36m (0.2ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
94
|
+
[1m[36m (0.3ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
95
|
+
[1m[35m (0.2ms)[0m CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar)
|
96
|
+
[1m[36m (0.1ms)[0m [1mCREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "capital" varchar, "comment" varchar) [0m
|
metadata
CHANGED
@@ -1,44 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: column_hider
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Flashfunders
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.2
|
19
|
+
version: '4.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.2
|
26
|
+
version: '4.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sqlite3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.3'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
description: Superclasses the
|
40
|
+
version: '1.3'
|
41
|
+
description: Superclasses the "columns method" of ActiveRecords Attribute class and
|
42
42
|
dynamically removes your chosen column(s).
|
43
43
|
email:
|
44
44
|
- engineering@flashfunders.com
|
@@ -47,7 +47,7 @@ extensions: []
|
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
49
|
- MIT-LICENSE
|
50
|
-
- README.
|
50
|
+
- README.md
|
51
51
|
- Rakefile
|
52
52
|
- lib/column_hider.rb
|
53
53
|
- lib/column_hider/version.rb
|