secretary-rails 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +186 -0
- data/Rakefile +9 -0
- data/app/models/secretary/version.rb +93 -0
- data/lib/generators/secretary/install_generator.rb +23 -0
- data/lib/generators/secretary/templates/versions_migration.rb +18 -0
- data/lib/secretary/config.rb +19 -0
- data/lib/secretary/engine.rb +4 -0
- data/lib/secretary/errors.rb +10 -0
- data/lib/secretary/gem_version.rb +3 -0
- data/lib/secretary/has_secretary.rb +75 -0
- data/lib/secretary/tracks_association.rb +146 -0
- data/lib/secretary/versioned_attributes.rb +58 -0
- data/lib/secretary-rails.rb +3 -0
- data/lib/secretary.rb +40 -0
- data/lib/tasks/secretary_tasks.rake +6 -0
- data/spec/factories.rb +32 -0
- data/spec/internal/app/models/animal.rb +7 -0
- data/spec/internal/app/models/hobby.rb +3 -0
- data/spec/internal/app/models/location.rb +6 -0
- data/spec/internal/app/models/person.rb +14 -0
- data/spec/internal/app/models/story.rb +3 -0
- data/spec/internal/app/models/user.rb +3 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +2 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +50 -0
- data/spec/internal/log/test.log +23177 -0
- data/spec/lib/generators/secretary/install_generator_spec.rb +17 -0
- data/spec/lib/secretary/config_spec.rb +9 -0
- data/spec/lib/secretary/has_secretary_spec.rb +116 -0
- data/spec/lib/secretary/tracks_association_spec.rb +214 -0
- data/spec/lib/secretary/versioned_attributes_spec.rb +63 -0
- data/spec/lib/secretary_spec.rb +44 -0
- data/spec/models/secretary/version_spec.rb +68 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/tmp/db/migrate/20131105082639_create_versions.rb +18 -0
- metadata +181 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'generator_spec/test_case'
|
3
|
+
require 'generators/secretary/install_generator'
|
4
|
+
|
5
|
+
describe Secretary::InstallGenerator do
|
6
|
+
include GeneratorSpec::TestCase
|
7
|
+
destination File.expand_path("../../../../tmp", __FILE__)
|
8
|
+
|
9
|
+
before do
|
10
|
+
prepare_destination
|
11
|
+
run_generator
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'copies the migration file' do
|
15
|
+
assert_migration "db/migrate/create_versions"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Secretary::HasSecretary do
|
4
|
+
let(:user) { create :user }
|
5
|
+
|
6
|
+
let(:new_story) {
|
7
|
+
build :story,
|
8
|
+
:headline => "Cool Story, Bro",
|
9
|
+
:body => "Some cool text.",
|
10
|
+
:logged_user_id => user.id
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:other_story) {
|
14
|
+
create :story,
|
15
|
+
:headline => "Cooler Story, Bro",
|
16
|
+
:body => "Some cooler text.",
|
17
|
+
:logged_user_id => user.id
|
18
|
+
}
|
19
|
+
|
20
|
+
|
21
|
+
describe "::has_secretary?" do
|
22
|
+
it "returns false if no has_secretary declared" do
|
23
|
+
User.has_secretary?.should eq false
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns true if @_has_secretary is true" do
|
27
|
+
Story.has_secretary?.should eq true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
describe "::has_secretary" do
|
33
|
+
it "sets @_has_secretary to true" do
|
34
|
+
Story.has_secretary?.should eq true
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'adds the model to Secretary.versioned_models' do
|
38
|
+
Story # Load the class
|
39
|
+
Secretary.versioned_models.should include "Story"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "adds the has_many association for versions" do
|
43
|
+
new_story.versions.to_a.should eq Array.new
|
44
|
+
end
|
45
|
+
|
46
|
+
it "has logged_user_id" do
|
47
|
+
new_story.should respond_to :logged_user_id
|
48
|
+
new_story.should respond_to :logged_user_id=
|
49
|
+
end
|
50
|
+
|
51
|
+
it "generates a version on create" do
|
52
|
+
Secretary::Version.count.should eq 0
|
53
|
+
new_story.save!
|
54
|
+
Secretary::Version.count.should eq 1
|
55
|
+
new_story.versions.count.should eq 1
|
56
|
+
end
|
57
|
+
|
58
|
+
it "generates a version when a record is changed" do
|
59
|
+
other_story.update_attributes(headline: "Some Cool Headline?!")
|
60
|
+
Secretary::Version.count.should eq 2
|
61
|
+
other_story.versions.size.should eq 2
|
62
|
+
end
|
63
|
+
|
64
|
+
it "doesn't generate a version if no attributes were changed" do
|
65
|
+
other_story.save!
|
66
|
+
other_story.versions.size.should eq 1
|
67
|
+
other_story.save!
|
68
|
+
other_story.versions.size.should eq 1
|
69
|
+
end
|
70
|
+
|
71
|
+
it "destroys all versions when the object is destroyed" do
|
72
|
+
other_story.update_attributes!(headline: "Changed the headline")
|
73
|
+
other_story.versions.size.should eq 2
|
74
|
+
Secretary::Version.count.should eq 2
|
75
|
+
other_story.destroy
|
76
|
+
Secretary::Version.count.should eq 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
describe '#changes' do
|
82
|
+
it 'is the built-in changes reverse-merged with custom changes' do
|
83
|
+
story = create :story, headline: "Original Headline"
|
84
|
+
story.headline = "Updated Headline!"
|
85
|
+
story.custom_changes['assets'] = [[], { a: 1, b: 2 }]
|
86
|
+
|
87
|
+
story.changes.should eq Hash[{
|
88
|
+
'headline' => ['Original Headline', "Updated Headline!"],
|
89
|
+
'assets' => [[], { 'a' => 1, 'b' => 2 }]
|
90
|
+
}]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
describe '#changed?' do
|
96
|
+
it 'checks if custom changes are present as well' do
|
97
|
+
other_story.changed?.should eq false
|
98
|
+
other_story.custom_changes['assets'] = [[], { a: 1, b: 2 }]
|
99
|
+
other_story.changed?.should eq true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
describe '#custom_changes' do
|
105
|
+
it 'is a hash into which you can put things' do
|
106
|
+
other_story.custom_changes['something'] = ['old', 'new']
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'gets cleared after saved' do
|
110
|
+
other_story.custom_changes["something"] = ["old", "new"]
|
111
|
+
other_story.custom_changes.should eq Hash[{"something" => ["old", "new"]}]
|
112
|
+
other_story.save!
|
113
|
+
other_story.custom_changes.should eq Hash[]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Secretary::TracksAssociation do
|
4
|
+
describe '::tracks_association' do
|
5
|
+
it "raises an error if the model isn't versioned" do
|
6
|
+
-> {
|
7
|
+
User.tracks_association
|
8
|
+
}.should raise_error Secretary::NotVersionedError
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'adds the associations to the versioned attributes' do
|
12
|
+
Person.versioned_attributes.should include "animals"
|
13
|
+
Person.versioned_attributes.should include "hobbies"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
describe 'dirty association' do
|
19
|
+
let(:person) { create :person }
|
20
|
+
let(:animal) { create :animal }
|
21
|
+
|
22
|
+
it 'sets associations_were' do
|
23
|
+
person.animals << animal
|
24
|
+
person.animals_were.should eq []
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'marks the association as changed when the association is changed' do
|
28
|
+
person.animals << animal
|
29
|
+
person.animals_changed?.should eq true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'clears out the dirty association after commit' do
|
33
|
+
person.animals << animal
|
34
|
+
person.animals_changed?.should eq true
|
35
|
+
person.save!
|
36
|
+
person.animals_changed?.should eq false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
describe "adding to association collections" do
|
42
|
+
let(:person) { create :person }
|
43
|
+
let(:animal) { build :animal, name: "Bob", color: "dog" }
|
44
|
+
|
45
|
+
it "creates a new version when adding" do
|
46
|
+
person.animals = [animal]
|
47
|
+
person.save!
|
48
|
+
|
49
|
+
person.versions.count.should eq 2
|
50
|
+
version = person.versions.last
|
51
|
+
version.object_changes["animals"][0].should eq []
|
52
|
+
|
53
|
+
version.object_changes["animals"][1].should eq [
|
54
|
+
{"name" => "Bob", "color" => "dog"}
|
55
|
+
]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'makes a version when adding' do
|
59
|
+
person = create :person
|
60
|
+
animal = build :animal, name: "Bryan", color: 'lame'
|
61
|
+
|
62
|
+
person.animals << animal
|
63
|
+
person.save!
|
64
|
+
person.versions.count.should eq 2
|
65
|
+
|
66
|
+
versions = person.versions.order('version_number').to_a
|
67
|
+
versions.last.object_changes["animals"][0].should eq []
|
68
|
+
versions.last.object_changes["animals"][1].should eq [{
|
69
|
+
"name" => "Bryan",
|
70
|
+
"color" => "lame"
|
71
|
+
}]
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'makes a version when removing' do
|
75
|
+
person = build :person
|
76
|
+
animal = build :animal, name: "Bryan", color: 'lame'
|
77
|
+
person.animals = [animal]
|
78
|
+
person.save!
|
79
|
+
person.versions.count.should eq 1
|
80
|
+
|
81
|
+
person.animals = []
|
82
|
+
person.save!
|
83
|
+
person.versions.count.should eq 2
|
84
|
+
|
85
|
+
versions = person.versions.order('version_number').to_a
|
86
|
+
versions.last.object_changes["animals"][0].should eq [{
|
87
|
+
"name" => "Bryan",
|
88
|
+
"color" => "lame"
|
89
|
+
}]
|
90
|
+
versions.last.object_changes["animals"][1].should eq []
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
describe 'with accepts_nested_attributes_for' do
|
96
|
+
let(:animal) { create :animal, name: "Henry", color: "blind" }
|
97
|
+
let(:person) { create :person }
|
98
|
+
|
99
|
+
it 'adds a new version when adding to collection' do
|
100
|
+
animals_attributes = [
|
101
|
+
{
|
102
|
+
"name" => "George",
|
103
|
+
"color" => "yes"
|
104
|
+
}
|
105
|
+
]
|
106
|
+
|
107
|
+
person.animals_attributes = animals_attributes
|
108
|
+
person.save!
|
109
|
+
person.versions.count.should eq 2
|
110
|
+
|
111
|
+
version = person.versions.order('version_number').last
|
112
|
+
version.object_changes["animals"][0].should eq []
|
113
|
+
version.object_changes["animals"][1].should eq [{
|
114
|
+
"name" => "George",
|
115
|
+
"color" => "yes"
|
116
|
+
}]
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'adds a new version when changing something in collection' do
|
120
|
+
animals_attributes = [
|
121
|
+
{
|
122
|
+
"id" => animal.id,
|
123
|
+
"name" => "Lemon"
|
124
|
+
}
|
125
|
+
]
|
126
|
+
|
127
|
+
person.animals << animal
|
128
|
+
person.save!
|
129
|
+
person.versions.count.should eq 2
|
130
|
+
person.animals_attributes = animals_attributes
|
131
|
+
person.save!
|
132
|
+
person.versions.count.should eq 3
|
133
|
+
|
134
|
+
version = person.versions.order('version_number').last
|
135
|
+
version.object_changes["animals"][0].should eq [{
|
136
|
+
"name" => "Henry",
|
137
|
+
"color" => "blind"
|
138
|
+
}]
|
139
|
+
version.object_changes["animals"][1].should eq [{
|
140
|
+
"name" => "Lemon",
|
141
|
+
"color" => "blind"
|
142
|
+
}]
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'adds a new version when removing something from collection' do
|
146
|
+
animals_attributes = [
|
147
|
+
{
|
148
|
+
"id" => animal.id,
|
149
|
+
"_destroy" => "1"
|
150
|
+
}
|
151
|
+
]
|
152
|
+
|
153
|
+
person.animals << animal
|
154
|
+
person.save!
|
155
|
+
person.versions.count.should eq 2
|
156
|
+
person.animals_attributes = animals_attributes
|
157
|
+
person.save!
|
158
|
+
person.versions.count.should eq 3
|
159
|
+
|
160
|
+
version = person.versions.order('version_number').last
|
161
|
+
version.object_changes["animals"][0].should eq [{
|
162
|
+
"name" => "Henry",
|
163
|
+
"color" => "blind"
|
164
|
+
}]
|
165
|
+
version.object_changes["animals"][1].should eq []
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'does not add a new version if nothing has changed' do
|
169
|
+
animals_attributes = [
|
170
|
+
{
|
171
|
+
"id" => animal.id,
|
172
|
+
"name" => "Henry"
|
173
|
+
}
|
174
|
+
]
|
175
|
+
|
176
|
+
person.animals << animal
|
177
|
+
person.save!
|
178
|
+
person.versions.count.should eq 2
|
179
|
+
# this doesn't call before_add/remove callbacks
|
180
|
+
person.animals_attributes = animals_attributes
|
181
|
+
person.save!
|
182
|
+
person.versions.count.should eq 2
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
describe '#association_changed?' do
|
188
|
+
let(:person) { create :person }
|
189
|
+
let(:animal) { create :animal }
|
190
|
+
|
191
|
+
it 'is true if the association has changed' do
|
192
|
+
person.animals_changed?.should eq false
|
193
|
+
person.animals << animal
|
194
|
+
person.animals_changed?.should eq true
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'is false after the parent object has been saved' do
|
198
|
+
person.animals << animal
|
199
|
+
person.animals_changed?.should eq true
|
200
|
+
person.save!
|
201
|
+
person.animals_changed?.should eq false
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'is false if the association has not changed' do
|
205
|
+
person.animals << animal
|
206
|
+
person.animals_changed?.should eq true
|
207
|
+
person.save!
|
208
|
+
person.animals_changed?.should eq false
|
209
|
+
|
210
|
+
person.animals = [animal]
|
211
|
+
person.animals_changed?.should eq false
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Secretary::VersionedAttributes do
|
4
|
+
describe '::versioned_attributes' do
|
5
|
+
it 'uses the attributes set in the model' do
|
6
|
+
Animal.versioned_attributes.should eq ["name", "color"]
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'uses the column names minus the global ignores if nothing is set' do
|
10
|
+
Location.versioned_attributes.should eq ["title", "address", "people"]
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'subtracts unversioned attributes if they are set' do
|
14
|
+
Person.versioned_attributes.should_not include "name"
|
15
|
+
Person.versioned_attributes.should_not include "ethnicity"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe '#versioned_changes' do
|
21
|
+
let(:person) { create :person }
|
22
|
+
|
23
|
+
it 'is empty for non-dirty objects' do
|
24
|
+
person.versioned_changes.should eq Hash[]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "return a hash of changes for just the attributes we want" do
|
28
|
+
person.age = 120
|
29
|
+
person.name = "Freddie"
|
30
|
+
|
31
|
+
person.versioned_changes.should eq Hash[{
|
32
|
+
"age" => [100, 120]
|
33
|
+
}]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe '#versioned_attributes' do
|
39
|
+
let(:animal) { create :animal, name: "Henry", color: "henry" }
|
40
|
+
|
41
|
+
it 'is only the attributes we want' do
|
42
|
+
animal.versioned_attributes.should eq Hash[{
|
43
|
+
"name" => "Henry",
|
44
|
+
"color" => "henry"
|
45
|
+
}]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
describe '#versioned_attribute?' do
|
51
|
+
let(:person) { create :person }
|
52
|
+
|
53
|
+
it 'is true if the attribute should be versioned' do
|
54
|
+
person.versioned_attribute?("age").should eq true
|
55
|
+
person.versioned_attribute?(:age).should eq true
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'is false if the attribute should not be versioned' do
|
59
|
+
person.versioned_attribute?("name").should eq false
|
60
|
+
person.versioned_attribute?("id").should eq false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Secretary do
|
4
|
+
describe "::configure" do
|
5
|
+
it "accepts a block with the config object" do
|
6
|
+
Secretary.configure do |config|
|
7
|
+
config.should be_a Secretary::Config
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "sets Secretary.config to the new Config object" do
|
12
|
+
config = Secretary.configure
|
13
|
+
Secretary.config.should eq config
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
describe '::config' do
|
19
|
+
it 'creates a new configuration if none is set' do
|
20
|
+
Secretary.config.should be_a Secretary::Config
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'uses the set configuration if available' do
|
24
|
+
id = Secretary.configure.object_id
|
25
|
+
Secretary.config.object_id.should eq id
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe '::versioned_models' do
|
31
|
+
it 'lists the name of all the versioned models' do
|
32
|
+
Story # load the class
|
33
|
+
Secretary.versioned_models.should include "Story"
|
34
|
+
|
35
|
+
class Something < ActiveRecord::Base
|
36
|
+
self.table_name = "stories"
|
37
|
+
has_secretary
|
38
|
+
end
|
39
|
+
|
40
|
+
Secretary.versioned_models.should include "Story"
|
41
|
+
Secretary.versioned_models.should include "Something"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Secretary::Version do
|
4
|
+
describe "::generate" do
|
5
|
+
it "generates a new version for passed-in object" do
|
6
|
+
story = create :story
|
7
|
+
version = Secretary::Version.generate(story)
|
8
|
+
|
9
|
+
Secretary::Version.count.should eq 2
|
10
|
+
story.versions.last.should eq version
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
describe "generating description" do
|
16
|
+
let(:story) {
|
17
|
+
build :story, headline: "Cool story, bro", body: "Cool text, bro."
|
18
|
+
}
|
19
|
+
|
20
|
+
it "generates a description with object name on create" do
|
21
|
+
story.save!
|
22
|
+
story.versions.last.description.should eq "Created Story ##{story.id}"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "generates a description with the changed attributes on update" do
|
26
|
+
story.save!
|
27
|
+
story.update_attributes(headline: "Another Headline", body: "New Body")
|
28
|
+
story.versions.last.description.should eq "Changed headline and body"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe "incrementing version number" do
|
34
|
+
it "sets version_number to 1 if no other versions exist for this object" do
|
35
|
+
story = create :story
|
36
|
+
story.versions.last.version_number.should eq 1
|
37
|
+
end
|
38
|
+
|
39
|
+
it "increments version number if versions already exist" do
|
40
|
+
story = create :story, headline: "Some Headline"
|
41
|
+
story.versions.last.version_number.should eq 1
|
42
|
+
story.update_attributes(headline: "Cooler story, bro.")
|
43
|
+
story.versions.last.version_number.should eq 2
|
44
|
+
story.update_attributes(headline: "Coolest story, bro!")
|
45
|
+
story.versions.last.version_number.should eq 3
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
describe '#attribute_diffs' do
|
51
|
+
it 'is a hash of attribute keys, and Diffy::Diff objects' do
|
52
|
+
story = create :story, headline: "Cool story, bro"
|
53
|
+
story.update_attributes!(headline: "Updated Headline")
|
54
|
+
|
55
|
+
version = story.versions.last
|
56
|
+
version.attribute_diffs.keys.should eq ["headline"]
|
57
|
+
version.attribute_diffs["headline"].should be_a Diffy::Diff
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
describe '#title' do
|
63
|
+
it "is the simple title for the version" do
|
64
|
+
story = create :story
|
65
|
+
story.versions.last.title.should eq "Story ##{story.id} v1"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= 'test'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
require 'combustion'
|
7
|
+
Combustion.initialize! :active_record
|
8
|
+
|
9
|
+
require 'rspec/rails'
|
10
|
+
require 'factory_girl'
|
11
|
+
load 'factories.rb'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.use_transactional_fixtures = true
|
15
|
+
config.include FactoryGirl::Syntax::Methods
|
16
|
+
config.mock_with :rspec
|
17
|
+
config.order = "random"
|
18
|
+
config.filter_run focus: true
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class SecretaryCreateVersions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table "versions" do |t|
|
4
|
+
t.integer "version_number"
|
5
|
+
t.string "versioned_type"
|
6
|
+
t.integer "versioned_id"
|
7
|
+
t.string "user_id"
|
8
|
+
t.text "description"
|
9
|
+
t.text "object_changes"
|
10
|
+
t.datetime "created_at"
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index "versions", ["created_at"]
|
14
|
+
add_index "versions", ["user_id"]
|
15
|
+
add_index "versions", ["version_number"]
|
16
|
+
add_index "versions", ["versioned_type", "versioned_id"]
|
17
|
+
end
|
18
|
+
end
|