historiographer 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bde50424be173ef43918d0e7b09b9c436f74c6d113ebebece1ece6b052fa70f
4
- data.tar.gz: c07f1eb52ce276436c52a5f199f0b3e27ae4c91995f64b1dd5b1a47ef02207aa
3
+ metadata.gz: 193d6326a6d665c589bcf2c67c16434b3cbf6e4bacd1b1d2f28f80d6ce3b229c
4
+ data.tar.gz: 1e09d0ecf55bf816d444376fc11cbf00a38a8c9f2a2c6ebbbf62f6a7d173282d
5
5
  SHA512:
6
- metadata.gz: 701c46dee8eb4934869954f5c85d845b769842915dcec2721d2fce305874b419f2f08526754ac9458cf63b7eaa6a0a5bf551608de9115fd08ff5e83bd7a56af7
7
- data.tar.gz: 5817b1a4c4d2288437bd5b624c788c1b91876f46e842b4d5c4ac1c25f0068e4657bb24c9a61b177c9e9d9432a7899c488aea66addc22c4c4766cac6b1940c479
6
+ metadata.gz: 32854e876a7a557c8c0c7008b93cfaf33bd5e06748c97f86890cdcfc269b5baef958555ada0c49c551f035b9b655c41a7036debb908347e028554ec1c55ea5fb
7
+ data.tar.gz: 3a27716e6159f01260bbb682309d9a82b1bf261cb3ba3eae13f38d8265894a99db938c1473b24a465c63ae24dbf27d0a4d7d66c9a823bf5e16ed0ce6fd8cab6a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.1.0
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: historiographer 3.0.0 ruby lib
5
+ # stub: historiographer 3.1.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "historiographer".freeze
9
- s.version = "3.0.0"
9
+ s.version = "3.1.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["brettshollenberger".freeze]
14
- s.date = "2022-10-13"
14
+ s.date = "2022-10-18"
15
15
  s.description = "Creates separate tables for each history table".freeze
16
16
  s.email = "brett.shollenberger@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -40,6 +40,7 @@ Gem::Specification.new do |s|
40
40
  "lib/historiographer/postgres_migration.rb",
41
41
  "lib/historiographer/relation.rb",
42
42
  "lib/historiographer/safe.rb",
43
+ "lib/historiographer/silent.rb",
43
44
  "spec/db/database.yml",
44
45
  "spec/db/migrate/20161121212228_create_posts.rb",
45
46
  "spec/db/migrate/20161121212229_create_post_histories.rb",
@@ -51,6 +52,8 @@ Gem::Specification.new do |s|
51
52
  "spec/db/migrate/20191024142304_create_thing_with_compound_index.rb",
52
53
  "spec/db/migrate/20191024142352_create_thing_with_compound_index_history.rb",
53
54
  "spec/db/migrate/20191024203106_create_thing_without_history.rb",
55
+ "spec/db/migrate/20221018204220_create_silent_posts.rb",
56
+ "spec/db/migrate/20221018204255_create_silent_post_histories.rb",
54
57
  "spec/db/schema.rb",
55
58
  "spec/examples.txt",
56
59
  "spec/factories/post.rb",
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Historiographer::Silent is intended to be used to migrate an existing model
4
+ # to Historiographer, not as a long-term solution.
5
+ #
6
+ # Historiographer will throw an error if a model is saved without a user present,
7
+ # unless you explicitly call save_without_history.
8
+ #
9
+ # Historiographer::Silent will not throw an error, and will not produce a Rollbar
10
+ #
11
+ module Historiographer
12
+ module Silent
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ include Historiographer
17
+
18
+ def should_validate_history_user_id_present?
19
+ false
20
+ end
21
+
22
+ private
23
+
24
+ def history_user_absent_action
25
+ # noop
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateSilentPosts < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :silent_posts do |t|
6
+ t.string :title, null: false
7
+ t.text :body, null: false
8
+ t.integer :author_id, null: false
9
+ t.boolean :enabled, default: false
10
+ t.datetime :live_at
11
+ t.datetime :deleted_at
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :silent_posts, :author_id
17
+ add_index :silent_posts, :enabled
18
+ add_index :silent_posts, :live_at
19
+ add_index :silent_posts, :deleted_at
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'historiographer/postgres_migration'
4
+
5
+ class CreateSilentPostHistories < ActiveRecord::Migration[5.1]
6
+ def change
7
+ create_table :silent_post_histories, &:histories
8
+ end
9
+ end
data/spec/db/schema.rb CHANGED
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2019_10_24_203106) do
13
+ ActiveRecord::Schema.define(version: 2022_10_18_204255) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -117,6 +117,44 @@ ActiveRecord::Schema.define(version: 2019_10_24_203106) do
117
117
  t.index ["live_at"], name: "index_safe_posts_on_live_at"
118
118
  end
119
119
 
120
+ create_table "silent_post_histories", force: :cascade do |t|
121
+ t.integer "silent_post_id", null: false
122
+ t.string "title", null: false
123
+ t.text "body", null: false
124
+ t.integer "author_id", null: false
125
+ t.boolean "enabled", default: false
126
+ t.datetime "live_at"
127
+ t.datetime "deleted_at"
128
+ t.datetime "created_at", null: false
129
+ t.datetime "updated_at", null: false
130
+ t.datetime "history_started_at", null: false
131
+ t.datetime "history_ended_at"
132
+ t.integer "history_user_id"
133
+ t.index ["author_id"], name: "index_silent_post_histories_on_author_id"
134
+ t.index ["deleted_at"], name: "index_silent_post_histories_on_deleted_at"
135
+ t.index ["enabled"], name: "index_silent_post_histories_on_enabled"
136
+ t.index ["history_ended_at"], name: "index_silent_post_histories_on_history_ended_at"
137
+ t.index ["history_started_at"], name: "index_silent_post_histories_on_history_started_at"
138
+ t.index ["history_user_id"], name: "index_silent_post_histories_on_history_user_id"
139
+ t.index ["live_at"], name: "index_silent_post_histories_on_live_at"
140
+ t.index ["silent_post_id"], name: "index_silent_post_histories_on_silent_post_id"
141
+ end
142
+
143
+ create_table "silent_posts", force: :cascade do |t|
144
+ t.string "title", null: false
145
+ t.text "body", null: false
146
+ t.integer "author_id", null: false
147
+ t.boolean "enabled", default: false
148
+ t.datetime "live_at"
149
+ t.datetime "deleted_at"
150
+ t.datetime "created_at", null: false
151
+ t.datetime "updated_at", null: false
152
+ t.index ["author_id"], name: "index_silent_posts_on_author_id"
153
+ t.index ["deleted_at"], name: "index_silent_posts_on_deleted_at"
154
+ t.index ["enabled"], name: "index_silent_posts_on_enabled"
155
+ t.index ["live_at"], name: "index_silent_posts_on_live_at"
156
+ end
157
+
120
158
  create_table "thing_with_compound_index_histories", force: :cascade do |t|
121
159
  t.integer "thing_with_compound_index_id", null: false
122
160
  t.string "key"
@@ -1,4 +1,6 @@
1
- require "spec_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
2
4
 
3
5
  class Post < ActiveRecord::Base
4
6
  include Historiographer
@@ -16,6 +18,14 @@ end
16
18
  class SafePostHistory < ActiveRecord::Base
17
19
  end
18
20
 
21
+ class SilentPost < ActiveRecord::Base
22
+ include Historiographer::Silent
23
+ acts_as_paranoid
24
+ end
25
+
26
+ class SilentPostHistory < ActiveRecord::Base
27
+ end
28
+
19
29
  class Author < ActiveRecord::Base
20
30
  include Historiographer
21
31
  end
@@ -45,7 +55,7 @@ describe Historiographer do
45
55
  Timecop.return
46
56
  end
47
57
 
48
- let(:username) { "Test User" }
58
+ let(:username) { 'Test User' }
49
59
 
50
60
  let(:user) do
51
61
  User.create(name: username)
@@ -53,8 +63,8 @@ describe Historiographer do
53
63
 
54
64
  let(:create_post) do
55
65
  Post.create(
56
- title: "Post 1",
57
- body: "Great post",
66
+ title: 'Post 1',
67
+ body: 'Great post',
58
68
  author_id: 1,
59
69
  history_user_id: user.id
60
70
  )
@@ -62,43 +72,43 @@ describe Historiographer do
62
72
 
63
73
  let(:create_author) do
64
74
  Author.create(
65
- full_name: "Breezy",
75
+ full_name: 'Breezy',
66
76
  history_user_id: user.id
67
77
  )
68
78
  end
69
79
 
70
- describe "History counting" do
71
- it "creates history on creation of primary model record" do
72
- expect {
80
+ describe 'History counting' do
81
+ it 'creates history on creation of primary model record' do
82
+ expect do
73
83
  create_post
74
- }.to change {
84
+ end.to change {
75
85
  PostHistory.count
76
86
  }.by 1
77
87
  end
78
88
 
79
- it "appends new history on update" do
89
+ it 'appends new history on update' do
80
90
  post = create_post
81
91
 
82
- expect {
83
- post.update(title: "Better Title")
84
- }.to change {
92
+ expect do
93
+ post.update(title: 'Better Title')
94
+ end.to change {
85
95
  PostHistory.count
86
96
  }.by 1
87
97
  end
88
98
 
89
- it "does not append new history if nothing has changed" do
99
+ it 'does not append new history if nothing has changed' do
90
100
  post = create_post
91
101
 
92
- expect {
102
+ expect do
93
103
  post.update(title: post.title)
94
- }.to_not change {
104
+ end.to_not change {
95
105
  PostHistory.count
96
106
  }
97
107
  end
98
108
  end
99
109
 
100
- describe "History recording" do
101
- it "records all fields from the parent" do
110
+ describe 'History recording' do
111
+ it 'records all fields from the parent' do
102
112
  post = create_post
103
113
  post_history = post.histories.first
104
114
 
@@ -110,8 +120,8 @@ describe Historiographer do
110
120
  expect(post_history.history_ended_at).to be_nil
111
121
  expect(post_history.history_user_id).to eq user.id
112
122
 
113
- post.update(title: "Better title")
114
- post_histories = post.histories.reload.order("id asc")
123
+ post.update(title: 'Better title')
124
+ post_histories = post.histories.reload.order('id asc')
115
125
  first_history = post_histories.first
116
126
  second_history = post_histories.second
117
127
 
@@ -119,24 +129,24 @@ describe Historiographer do
119
129
  expect(second_history.history_ended_at).to be_nil
120
130
  end
121
131
 
122
- it "cannot create without history_user_id" do
132
+ it 'cannot create without history_user_id' do
123
133
  post = Post.create(
124
- title: "Post 1",
125
- body: "Great post",
126
- author_id: 1,
127
- )
128
- expect(post.errors.to_h).to eq({ :history_user_id => "must be an integer" })
134
+ title: 'Post 1',
135
+ body: 'Great post',
136
+ author_id: 1
137
+ )
138
+ expect(post.errors.to_h).to eq(history_user_id: 'must be an integer')
129
139
 
130
- expect {
140
+ expect do
131
141
  post.send(:record_history)
132
- }.to raise_error(
142
+ end.to raise_error(
133
143
  Historiographer::HistoryUserIdMissingError
134
144
  )
135
145
  end
136
146
 
137
- context "When directly hitting the database via SQL" do
138
- context "#update_all" do
139
- it "still updates histories" do
147
+ context 'When directly hitting the database via SQL' do
148
+ context '#update_all' do
149
+ it 'still updates histories' do
140
150
  FactoryBot.create_list(:post, 3, history_user_id: 1)
141
151
 
142
152
  posts = Post.all
@@ -144,12 +154,12 @@ describe Historiographer do
144
154
  expect(PostHistory.count).to eq 3
145
155
  expect(posts.map(&:histories).map(&:count)).to all (eq 1)
146
156
 
147
- posts.update_all(title: "My New Post Title", history_user_id: 1)
157
+ posts.update_all(title: 'My New Post Title', history_user_id: 1)
148
158
 
149
159
  expect(PostHistory.count).to eq 6
150
160
  expect(PostHistory.current.count).to eq 3
151
161
  expect(posts.map(&:histories).map(&:count)).to all(eq 2)
152
- expect(posts.map(&:current_history).map(&:title)).to all (eq "My New Post Title")
162
+ expect(posts.map(&:current_history).map(&:title)).to all (eq 'My New Post Title')
153
163
  expect(Post.all).to respond_to :has_histories?
154
164
 
155
165
  # It can update by sub-query
@@ -159,10 +169,10 @@ describe Historiographer do
159
169
  expect(posts.second.histories.count).to eq 2
160
170
  expect(posts.third.histories.count).to eq 3
161
171
  expect(posts.first.title).to eq "Brett's Post"
162
- expect(posts.second.title).to eq "My New Post Title"
172
+ expect(posts.second.title).to eq 'My New Post Title'
163
173
  expect(posts.third.title).to eq "Brett's Post"
164
174
  expect(posts.first.current_history.title).to eq "Brett's Post"
165
- expect(posts.second.current_history.title).to eq "My New Post Title"
175
+ expect(posts.second.current_history.title).to eq 'My New Post Title'
166
176
  expect(posts.third.current_history.title).to eq "Brett's Post"
167
177
 
168
178
  # It does not update histories if nothing changed
@@ -170,23 +180,23 @@ describe Historiographer do
170
180
  posts = Post.all.reload.order(:id)
171
181
  expect(posts.map(&:histories).map(&:count)).to all(eq 3)
172
182
 
173
- posts.update_all_without_history(title: "Untracked")
183
+ posts.update_all_without_history(title: 'Untracked')
174
184
  expect(posts.first.histories.count).to eq 3
175
185
  expect(posts.second.histories.count).to eq 3
176
186
  expect(posts.third.histories.count).to eq 3
177
187
 
178
- thing1 = ThingWithoutHistory.create(name: "Thing 1")
179
- thing2 = ThingWithoutHistory.create(name: "Thing 2")
188
+ thing1 = ThingWithoutHistory.create(name: 'Thing 1')
189
+ thing2 = ThingWithoutHistory.create(name: 'Thing 2')
180
190
 
181
- ThingWithoutHistory.all.update_all(name: "Thing 3")
191
+ ThingWithoutHistory.all.update_all(name: 'Thing 3')
182
192
 
183
- expect(ThingWithoutHistory.all.map(&:name)).to all(eq "Thing 3")
193
+ expect(ThingWithoutHistory.all.map(&:name)).to all(eq 'Thing 3')
184
194
  expect(ThingWithoutHistory.all).to_not respond_to :has_histories?
185
195
  expect(ThingWithoutHistory.all).to_not respond_to :update_all_without_history
186
196
  expect(ThingWithoutHistory.all).to_not respond_to :delete_all_without_history
187
197
  end
188
-
189
- it "respects safety" do
198
+
199
+ it 'respects safety' do
190
200
  FactoryBot.create_list(:post, 3, history_user_id: 1)
191
201
 
192
202
  posts = Post.all
@@ -194,35 +204,35 @@ describe Historiographer do
194
204
  expect(PostHistory.count).to eq 3
195
205
  expect(posts.map(&:histories).map(&:count)).to all (eq 1)
196
206
 
197
- expect {
198
- posts.update_all(title: "My New Post Title")
199
- }.to raise_error
207
+ expect do
208
+ posts.update_all(title: 'My New Post Title')
209
+ end.to raise_error
200
210
 
201
211
  posts.reload.map(&:title).each do |title|
202
- expect(title).to_not eq "My New Post Title"
212
+ expect(title).to_not eq 'My New Post Title'
203
213
  end
204
214
 
205
215
  SafePost.create(
206
- title: "Post 1",
207
- body: "Great post",
208
- author_id: 1,
216
+ title: 'Post 1',
217
+ body: 'Great post',
218
+ author_id: 1
209
219
  )
210
220
 
211
221
  safe_posts = SafePost.all
212
222
 
213
- expect {
214
- safe_posts.update_all(title: "New One")
215
- }.to_not raise_error
223
+ expect do
224
+ safe_posts.update_all(title: 'New One')
225
+ end.to_not raise_error
216
226
 
217
- expect(safe_posts.map(&:title)).to all(eq "New One")
227
+ expect(safe_posts.map(&:title)).to all(eq 'New One')
218
228
  end
219
229
  end
220
230
 
221
- context "#delete_all" do
222
- it "includes histories when not paranoid" do
231
+ context '#delete_all' do
232
+ it 'includes histories when not paranoid' do
223
233
  Timecop.freeze
224
234
  authors = 3.times.map do
225
- Author.create(full_name: "Brett", history_user_id: 1)
235
+ Author.create(full_name: 'Brett', history_user_id: 1)
226
236
  end
227
237
  Author.delete_all(history_user_id: 1)
228
238
  expect(AuthorHistory.count).to eq 3
@@ -232,7 +242,7 @@ describe Historiographer do
232
242
  Timecop.return
233
243
  end
234
244
 
235
- it "includes histories when paranoid" do
245
+ it 'includes histories when paranoid' do
236
246
  Timecop.freeze
237
247
  posts = FactoryBot.create_list(:post, 3, history_user_id: 1)
238
248
  Post.delete_all(history_user_id: 1)
@@ -246,9 +256,9 @@ describe Historiographer do
246
256
  Timecop.return
247
257
  end
248
258
 
249
- it "allows delete_all_without_history" do
259
+ it 'allows delete_all_without_history' do
250
260
  authors = 3.times.map do
251
- Author.create(full_name: "Brett", history_user_id: 1)
261
+ Author.create(full_name: 'Brett', history_user_id: 1)
252
262
  end
253
263
  Author.all.delete_all_without_history
254
264
  expect(AuthorHistory.current.count).to eq 3
@@ -256,8 +266,8 @@ describe Historiographer do
256
266
  end
257
267
  end
258
268
 
259
- context "#destroy_all" do
260
- it "includes histories" do
269
+ context '#destroy_all' do
270
+ it 'includes histories' do
261
271
  Timecop.freeze
262
272
  posts = FactoryBot.create_list(:post, 3, history_user_id: 1)
263
273
  Post.destroy_all(history_user_id: 1)
@@ -271,7 +281,7 @@ describe Historiographer do
271
281
  Timecop.return
272
282
  end
273
283
 
274
- it "destroys without histories" do
284
+ it 'destroys without histories' do
275
285
  Timecop.freeze
276
286
  posts = FactoryBot.create_list(:post, 3, history_user_id: 1)
277
287
  Post.all.destroy_all_without_history
@@ -283,79 +293,125 @@ describe Historiographer do
283
293
  end
284
294
  end
285
295
 
286
- context "When Safe mode" do
287
- it "creates history without history_user_id" do
288
- expect(Rollbar).to receive(:error).with("history_user_id must be passed in order to save record with histories! If you are in a context with no history_user_id, explicitly call #save_without_history")
296
+ context 'When Safe mode' do
297
+ it 'creates history without history_user_id' do
298
+ expect(Rollbar).to receive(:error).with('history_user_id must be passed in order to save record with histories! If you are in a context with no history_user_id, explicitly call #save_without_history')
289
299
 
290
300
  post = SafePost.create(
291
- title: "Post 1",
292
- body: "Great post",
293
- author_id: 1,
294
- )
301
+ title: 'Post 1',
302
+ body: 'Great post',
303
+ author_id: 1
304
+ )
295
305
  expect(post.errors.to_h.keys).to be_empty
296
306
  expect(post).to be_persisted
297
307
  expect(post.histories.count).to eq 1
298
308
  expect(post.histories.first.history_user_id).to be_nil
299
309
  end
300
310
 
301
- it "creates history with history_user_id" do
311
+ it 'creates history with history_user_id' do
302
312
  expect(Rollbar).to_not receive(:error)
303
313
 
304
314
  post = SafePost.create(
305
- title: "Post 1",
306
- body: "Great post",
315
+ title: 'Post 1',
316
+ body: 'Great post',
307
317
  author_id: 1,
308
318
  history_user_id: user.id
309
- )
319
+ )
310
320
  expect(post.errors.to_h.keys).to be_empty
311
321
  expect(post).to be_persisted
312
322
  expect(post.histories.count).to eq 1
313
323
  expect(post.histories.first.history_user_id).to eq user.id
314
324
  end
315
325
 
316
- it "skips history creation if desired" do
326
+ it 'skips history creation if desired' do
317
327
  post = SafePost.new(
318
- title: "Post 1",
319
- body: "Great post",
328
+ title: 'Post 1',
329
+ body: 'Great post',
320
330
  author_id: 1
321
- )
331
+ )
322
332
 
323
333
  post.save_without_history
324
334
  expect(post).to be_persisted
325
335
  expect(post.histories.count).to eq 0
326
- end
336
+ end
327
337
  end
328
338
 
329
- it "can override without history_user_id" do
330
- expect {
331
- post = Post.new(
332
- title: "Post 1",
333
- body: "Great post",
339
+ context 'When Silent mode' do
340
+ it 'creates history without history_user_id' do
341
+ expect(Rollbar).to_not receive(:error)
342
+
343
+ post = SilentPost.create(
344
+ title: 'Post 1',
345
+ body: 'Great post',
346
+ author_id: 1
347
+ )
348
+ expect(post.errors.to_h.keys).to be_empty
349
+ expect(post).to be_persisted
350
+ expect(post.histories.count).to eq 1
351
+ expect(post.histories.first.history_user_id).to be_nil
352
+
353
+ post.update(title: 'New Title')
354
+ post.reload
355
+ expect(post.title).to eq 'New Title' # No error was raised
356
+ end
357
+
358
+ it 'creates history with history_user_id' do
359
+ expect(Rollbar).to_not receive(:error)
360
+
361
+ post = SilentPost.create(
362
+ title: 'Post 1',
363
+ body: 'Great post',
334
364
  author_id: 1,
335
- )
365
+ history_user_id: user.id
366
+ )
367
+ expect(post.errors.to_h.keys).to be_empty
368
+ expect(post).to be_persisted
369
+ expect(post.histories.count).to eq 1
370
+ expect(post.histories.first.history_user_id).to eq user.id
371
+ end
372
+
373
+ it 'skips history creation if desired' do
374
+ post = SilentPost.new(
375
+ title: 'Post 1',
376
+ body: 'Great post',
377
+ author_id: 1
378
+ )
379
+
380
+ post.save_without_history
381
+ expect(post).to be_persisted
382
+ expect(post.histories.count).to eq 0
383
+ end
384
+ end
385
+ it 'can override without history_user_id' do
386
+ expect do
387
+ post = Post.new(
388
+ title: 'Post 1',
389
+ body: 'Great post',
390
+ author_id: 1
391
+ )
336
392
 
337
393
  post.save_without_history
338
- }.to_not raise_error
394
+ end.to_not raise_error
339
395
  end
340
396
 
341
- it "can override without history_user_id" do
342
- expect {
397
+ it 'can override without history_user_id' do
398
+ expect do
343
399
  post = Post.new(
344
- title: "Post 1",
345
- body: "Great post",
346
- author_id: 1,
347
- )
400
+ title: 'Post 1',
401
+ body: 'Great post',
402
+ author_id: 1
403
+ )
348
404
 
349
405
  post.save_without_history!
350
- }.to_not raise_error
406
+ end.to_not raise_error
351
407
  end
352
408
 
353
- it "does not record histories when main model fails to save" do
409
+ it 'does not record histories when main model fails to save' do
354
410
  class Post
355
411
  after_save :raise_error, prepend: true
356
412
 
357
413
  def raise_error
358
- raise "Oh no, db issue!"
414
+ raise 'Oh no, db issue!'
359
415
  end
360
416
  end
361
417
 
@@ -367,21 +423,21 @@ describe Historiographer do
367
423
  end
368
424
  end
369
425
 
370
- describe "Scopes" do
371
- it "finds current histories" do
426
+ describe 'Scopes' do
427
+ it 'finds current histories' do
372
428
  post1 = create_post
373
- post1.update(title: "Better title")
429
+ post1.update(title: 'Better title')
374
430
 
375
431
  post2 = create_post
376
- post2.update(title: "Better title")
432
+ post2.update(title: 'Better title')
377
433
 
378
- expect(PostHistory.current.pluck(:title)).to all eq "Better title"
379
- expect(post1.current_history.title).to eq "Better title"
434
+ expect(PostHistory.current.pluck(:title)).to all eq 'Better title'
435
+ expect(post1.current_history.title).to eq 'Better title'
380
436
  end
381
437
  end
382
438
 
383
- describe "Associations" do
384
- it "names associated records" do
439
+ describe 'Associations' do
440
+ it 'names associated records' do
385
441
  post1 = create_post
386
442
  expect(post1.histories.first).to be_a(PostHistory)
387
443
 
@@ -394,27 +450,27 @@ describe Historiographer do
394
450
  end
395
451
  end
396
452
 
397
- describe "Histories" do
398
- it "does not allow direct updates of histories" do
453
+ describe 'Histories' do
454
+ it 'does not allow direct updates of histories' do
399
455
  post1 = create_post
400
456
  hist1 = post1.histories.first
401
457
 
402
- expect(hist1.update(title: "A different title")).to be false
458
+ expect(hist1.update(title: 'A different title')).to be false
403
459
  expect(hist1.reload.title).to eq post1.title
404
460
 
405
- expect(hist1.update!(title: "A different title")).to be false
461
+ expect(hist1.update!(title: 'A different title')).to be false
406
462
  expect(hist1.reload.title).to eq post1.title
407
463
 
408
- hist1.title = "A different title"
464
+ hist1.title = 'A different title'
409
465
  expect(hist1.save).to be false
410
466
  expect(hist1.reload.title).to eq post1.title
411
467
 
412
- hist1.title = "A different title"
468
+ hist1.title = 'A different title'
413
469
  expect(hist1.save!).to be false
414
470
  expect(hist1.reload.title).to eq post1.title
415
471
  end
416
472
 
417
- it "does not allow destroys of histories" do
473
+ it 'does not allow destroys of histories' do
418
474
  post1 = create_post
419
475
  hist1 = post1.histories.first
420
476
  original_history_count = post1.histories.count
@@ -425,19 +481,19 @@ describe Historiographer do
425
481
  expect(post1.histories.count).to be original_history_count
426
482
  end
427
483
  end
428
-
429
- describe "Deletion" do
430
- it "records deleted_at and history_user_id on primary and history if you use acts_as_paranoid" do
484
+
485
+ describe 'Deletion' do
486
+ it 'records deleted_at and history_user_id on primary and history if you use acts_as_paranoid' do
431
487
  post = Post.create(
432
- title: "Post 1",
433
- body: "Great post",
488
+ title: 'Post 1',
489
+ body: 'Great post',
434
490
  author_id: 1,
435
491
  history_user_id: user.id
436
492
  )
437
493
 
438
- expect {
494
+ expect do
439
495
  post.destroy(history_user_id: 2)
440
- }.to change {
496
+ end.to change {
441
497
  PostHistory.count
442
498
  }.by 1
443
499
 
@@ -447,23 +503,23 @@ describe Historiographer do
447
503
  expect(PostHistory.last.history_user_id).to eq 2
448
504
  end
449
505
 
450
- it "works with Historiographer::Safe" do
451
- post = SafePost.create(title: "HELLO", body: "YO", author_id: 1)
506
+ it 'works with Historiographer::Safe' do
507
+ post = SafePost.create(title: 'HELLO', body: 'YO', author_id: 1)
452
508
 
453
- expect {
509
+ expect do
454
510
  post.destroy
455
- }.to_not raise_error
511
+ end.to_not raise_error
456
512
 
457
513
  expect(SafePost.count).to eq 0
458
514
  expect(post.deleted_at).to_not be_nil
459
515
  expect(SafePostHistory.count).to eq 2
460
516
  expect(SafePostHistory.current.last.deleted_at).to eq post.deleted_at
461
517
 
462
- post2 = SafePost.create(title: "HELLO", body: "YO", author_id: 1)
518
+ post2 = SafePost.create(title: 'HELLO', body: 'YO', author_id: 1)
463
519
 
464
- expect {
520
+ expect do
465
521
  post2.destroy!
466
- }.to_not raise_error
522
+ end.to_not raise_error
467
523
 
468
524
  expect(SafePost.count).to eq 0
469
525
  expect(post2.deleted_at).to_not be_nil
@@ -472,18 +528,18 @@ describe Historiographer do
472
528
  end
473
529
  end
474
530
 
475
- describe "Scopes" do
476
- it "finds current" do
531
+ describe 'Scopes' do
532
+ it 'finds current' do
477
533
  post = create_post
478
- post.update(title: "New Title")
479
- post.update(title: "New Title 2")
534
+ post.update(title: 'New Title')
535
+ post.update(title: 'New Title 2')
480
536
 
481
537
  expect(PostHistory.current.count).to be 1
482
538
  end
483
539
  end
484
540
 
485
- describe "User associations" do
486
- it "links to user" do
541
+ describe 'User associations' do
542
+ it 'links to user' do
487
543
  post = create_post
488
544
  author = create_author
489
545
 
@@ -492,10 +548,10 @@ describe Historiographer do
492
548
  end
493
549
  end
494
550
 
495
- describe "Migrations with compound indexes" do
496
- it "supports renaming compound indexes and migrating them to history tables" do
497
- indices_sql = %q(
498
- SELECT
551
+ describe 'Migrations with compound indexes' do
552
+ it 'supports renaming compound indexes and migrating them to history tables' do
553
+ indices_sql = "
554
+ SELECT
499
555
  DISTINCT(
500
556
  ARRAY_TO_STRING(ARRAY(
501
557
  SELECT pg_get_indexdef(idx.indexrelid, k + 1, true)
@@ -514,19 +570,19 @@ describe Historiographer do
514
570
  AND a.attnum = ANY(idx.indkey)
515
571
  AND t.relkind = 'r'
516
572
  AND t.relname = ?;
517
- )
573
+ "
518
574
 
519
575
  indices_query_array = [indices_sql, :thing_with_compound_index_histories]
520
576
  indices_sanitized_query = ThingWithCompoundIndexHistory.send(:sanitize_sql_array, indices_query_array)
521
577
 
522
- indexes = ThingWithCompoundIndexHistory.connection.execute(indices_sanitized_query).to_a.map(&:values).flatten.map { |i| i.split(",") }
578
+ indexes = ThingWithCompoundIndexHistory.connection.execute(indices_sanitized_query).to_a.map(&:values).flatten.map { |i| i.split(',') }
523
579
 
524
- expect(indexes).to include(["history_started_at"])
525
- expect(indexes).to include(["history_ended_at"])
526
- expect(indexes).to include(["history_user_id"])
527
- expect(indexes).to include(["id"])
528
- expect(indexes).to include(["key", "value"])
529
- expect(indexes).to include(["thing_with_compound_index_id"])
580
+ expect(indexes).to include(['history_started_at'])
581
+ expect(indexes).to include(['history_ended_at'])
582
+ expect(indexes).to include(['history_user_id'])
583
+ expect(indexes).to include(['id'])
584
+ expect(indexes).to include(%w[key value])
585
+ expect(indexes).to include(['thing_with_compound_index_id'])
530
586
  end
531
587
  end
532
588
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: historiographer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - brettshollenberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-13 00:00:00.000000000 Z
11
+ date: 2022-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -235,6 +235,7 @@ files:
235
235
  - lib/historiographer/postgres_migration.rb
236
236
  - lib/historiographer/relation.rb
237
237
  - lib/historiographer/safe.rb
238
+ - lib/historiographer/silent.rb
238
239
  - spec/db/database.yml
239
240
  - spec/db/migrate/20161121212228_create_posts.rb
240
241
  - spec/db/migrate/20161121212229_create_post_histories.rb
@@ -246,6 +247,8 @@ files:
246
247
  - spec/db/migrate/20191024142304_create_thing_with_compound_index.rb
247
248
  - spec/db/migrate/20191024142352_create_thing_with_compound_index_history.rb
248
249
  - spec/db/migrate/20191024203106_create_thing_without_history.rb
250
+ - spec/db/migrate/20221018204220_create_silent_posts.rb
251
+ - spec/db/migrate/20221018204255_create_silent_post_histories.rb
249
252
  - spec/db/schema.rb
250
253
  - spec/examples.txt
251
254
  - spec/factories/post.rb