draftsman 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4594a89239d63ca33dfc4b008728952b04ff3d77
4
- data.tar.gz: a41330672fbc6204b0a9b459db106b05cddb3675
3
+ metadata.gz: c75a20681563bfa82fba2f109838a5fb2688d043
4
+ data.tar.gz: 7f43cc039a9d07048fbdfc04cfd9f8c5ff764ce1
5
5
  SHA512:
6
- metadata.gz: 4a5197c59c7c471a2abeaf558274b19fa5938eba14b319ba09fe571bca17b7df2363122c87ff00dd9f4bbe34e83177056e904a535add241b7c702e2b1ce45c00
7
- data.tar.gz: 31ad8696e86643c2c230fd40df6c66510360db0c8c98728fb89c27902738cde76dc5575ee7b8baf09c5c1f2b8574c923a1279c25fa8d6fac12c85408c453ad54
6
+ metadata.gz: 032096c7295407be9a2ba40e8ccd51e5e595279fef880d0011145867c32ccf3df60e5a47282afeacc7a5b5022745cf0531d96b03cb34a43931577cdcbeabad85
7
+ data.tar.gz: 6eb88502e4c4f176cb85660614597eea419425d14a35ff2390ae0f6b9a71718fd7d84adce866f82ab904f605c9c82cd967881d2a037ac932a43376bef539544f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.3.1 - August 14, 2014
4
+
5
+ - Commit [aae737fcdf](https://github.com/live-editor/draftsman/commit/aae737fcdf48604bc480b1c9c141bf642c0f581c) - `skip` option not persisting skipped values correctly
6
+
3
7
  ## 0.3.0 - July 29, 2014
4
8
 
5
9
  - Commit [1e2a59f678](https://github.com/live-editor/draftsman/commit/1e2a59f678cc4d88222dfc1976d564b5649cd329) - Add support for PostgreSQL JSON data type for `object`, `object_changes`, and `previous_draft` columns.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- draftsman (0.3.0)
4
+ draftsman (0.3.1)
5
5
  activerecord (>= 3.0, < 5.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Draftsman v0.3.0 (alpha)
1
+ # Draftsman v0.3.1 (alpha)
2
2
 
3
3
  Draftsman is a Ruby gem that lets you create draft versions of your database records. If you're developing a system in
4
4
  need of simple drafts or a publishing approval queue, then Draftsman just might be what you need.
@@ -50,7 +50,7 @@ Works well with Rails, Sinatra, or any other application that depends on ActiveR
50
50
  Add Draftsman to your `Gemfile`.
51
51
 
52
52
  ```ruby
53
- gem 'draftsman', '0.3.0'
53
+ gem 'draftsman', '0.3.1'
54
54
  ```
55
55
 
56
56
  Or if you want to grab the latest from `master`:
@@ -474,6 +474,16 @@ However, there are some differences:
474
474
  as it was _before_ it was destroyed (in case you want the option of reverting the destroy later and restoring the
475
475
  drafted item back to its original state).
476
476
 
477
+ ## Semantic Versioning
478
+
479
+ Like many Ruby gems, Draftsman honors the concepts behind [semantic versioning][10]:
480
+
481
+ > Given a version number MAJOR.MINOR.PATCH, increment the:
482
+ >
483
+ > 1. MAJOR version when you make incompatible API changes,
484
+ > 2. MINOR version when you add functionality in a backwards-compatible manner, and
485
+ > 3. PATCH version when you make backwards-compatible bug fixes.
486
+
477
487
  ## Contributing
478
488
 
479
489
  If you feel like you can add something useful to Draftsman, then don't hesitate to contribute! To make sure your
@@ -521,3 +531,4 @@ Draftsman is released under the [MIT License][9].
521
531
  [7]: https://raw.github.com/live-editor/draftsman/master/lib/generators/draftsman/templates/create_drafts.rb
522
532
  [8]: http://www.sinatrarb.com/intro.html#Modular%20vs.%20Classic%20Style
523
533
  [9]: http://www.opensource.org/licenses/MIT
534
+ [10]: http://semver.org/
@@ -191,11 +191,6 @@ module Draftsman
191
191
  send(self.class.draft_association_name).present?
192
192
  end
193
193
 
194
- def draft_at(timestamp, reify_options = {})
195
- v = send(self.class.versions_association_name).following(timestamp).first
196
- v ? v.reify(reify_options) : self
197
- end
198
-
199
194
  # Creates object and records a draft for the object's creation. Returns `true` or `false` depending on whether or not
200
195
  # the objects passed validation and the save was successful.
201
196
  def draft_creation
@@ -292,14 +287,12 @@ module Draftsman
292
287
 
293
288
  data = merge_metadata_for_draft(data)
294
289
  send(self.class.draft_association_name).update_attributes data
295
-
296
290
  self.save
297
291
  # Destroy the draft if this record has changed back to the original record
298
292
  elsif changed_to_original_for_draft?
299
293
  send(self.class.draft_association_name).destroy
300
294
  send "#{self.class.draft_association_name}_id=", nil
301
- self.update_column "#{self.class.draft_association_name}_id", nil
302
- true
295
+ self.save
303
296
  # Save a draft if record is changed notably
304
297
  elsif changed_notably_for_draft?
305
298
  data = {
@@ -309,24 +302,24 @@ module Draftsman
309
302
  }
310
303
  data = merge_metadata_for_draft(data)
311
304
 
312
- # If there's already a draft, update it
305
+ # If there's already a draft, update it.
313
306
  if send(self.class.draft_association_name).present?
314
307
  data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
315
308
  send(self.class.draft_association_name).update_attributes data
316
- # If there's not draft, create an update draft
309
+ # If there's not draft, create an update draft.
317
310
  else
318
311
  data[:event] = 'update'
319
312
  data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
320
313
  send "build_#{self.class.draft_association_name}", data
321
314
 
322
315
  if send(self.class.draft_association_name).save
323
- write_attribute "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
324
- self.update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
316
+ update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
317
+ update_skipped_attributes
325
318
  else
326
319
  raise ActiveRecord::Rollback and return false
327
320
  end
328
321
  end
329
- # If record is a draft and not changed notably, then update the draft
322
+ # If record is a draft and not changed notably, then update the draft.
330
323
  elsif self.draft?
331
324
  data = {
332
325
  :item => self,
@@ -335,8 +328,8 @@ module Draftsman
335
328
  }
336
329
  data[:object_changes] = changes_for_draftsman(changed_from: @object.draft.changeset) if track_object_changes_for_draft?
337
330
  data = merge_metadata_for_draft(data)
338
-
339
331
  send(self.class.draft_association_name).update_attributes data
332
+ update_skipped_attributes
340
333
  # Otherwise, just save the record
341
334
  else
342
335
  self.save
@@ -469,6 +462,21 @@ module Draftsman
469
462
  write_attribute self.class.trashed_at_attribute_name, Time.now
470
463
  self.update_column self.class.trashed_at_attribute_name, send(self.class.trashed_at_attribute_name)
471
464
  end
465
+
466
+ # Updates skipped attributes' values on this model.
467
+ def update_skipped_attributes
468
+ if draftsman_options[:skip].present?
469
+ changed_and_skipped_keys = self.changed.select { |key| draftsman_options[:skip].include?(key) }
470
+ changed_and_skipped_attrs = {}
471
+ changed_and_skipped_keys.each { |key| changed_and_skipped_attrs[key] = self.changes[key].last }
472
+
473
+ self.reload
474
+ self.attributes = changed_and_skipped_attrs
475
+ self.save
476
+ else
477
+ true
478
+ end
479
+ end
472
480
  end
473
481
  end
474
482
  end
@@ -1,3 +1,3 @@
1
1
  module Draftsman
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -0,0 +1,3 @@
1
+ class Skipper < ActiveRecord::Base
2
+ has_drafts :skip => :skip_me
3
+ end
@@ -1,3 +1,3 @@
1
1
  class Whitelister < ActiveRecord::Base
2
- has_drafts only: [:name]
2
+ has_drafts :only => [:name]
3
3
  end
@@ -71,6 +71,15 @@ class SetUpTestTables < ActiveRecord::Migration
71
71
  t.references :parent
72
72
  t.timestamps
73
73
  end
74
+
75
+ create_table :skippers, :force => true do |t|
76
+ t.string :name
77
+ t.string :skip_me
78
+ t.references :draft
79
+ t.datetime :trashed_at
80
+ t.datetime :published_at
81
+ t.timestamps
82
+ end
74
83
  end
75
84
 
76
85
  def self.down
@@ -34,6 +34,15 @@ ActiveRecord::Schema.define(version: 20110208155312) do
34
34
  t.datetime "updated_at"
35
35
  end
36
36
 
37
+ create_table "clingy_parents", force: true do |t|
38
+ t.string "name"
39
+ t.integer "draft_id"
40
+ t.datetime "trashed_at"
41
+ t.datetime "published_at"
42
+ t.datetime "created_at"
43
+ t.datetime "updated_at"
44
+ end
45
+
37
46
  create_table "draft_as_sketches", force: true do |t|
38
47
  t.string "name"
39
48
  t.integer "sketch_id"
@@ -67,6 +76,26 @@ ActiveRecord::Schema.define(version: 20110208155312) do
67
76
  t.string "user_agent"
68
77
  end
69
78
 
79
+ create_table "hopeless_children", force: true do |t|
80
+ t.string "name"
81
+ t.integer "clingy_parent_id"
82
+ t.integer "draft_id"
83
+ t.datetime "trashed_at"
84
+ t.datetime "published_at"
85
+ t.datetime "created_at"
86
+ t.datetime "updated_at"
87
+ end
88
+
89
+ create_table "mortgages", force: true do |t|
90
+ t.float "amount"
91
+ t.integer "parent_id"
92
+ t.integer "draft_id"
93
+ t.datetime "trashed_at"
94
+ t.datetime "published_at"
95
+ t.datetime "created_at"
96
+ t.datetime "updated_at"
97
+ end
98
+
70
99
  create_table "parents", force: true do |t|
71
100
  t.string "name"
72
101
  t.integer "draft_id"
@@ -76,6 +105,16 @@ ActiveRecord::Schema.define(version: 20110208155312) do
76
105
  t.datetime "updated_at"
77
106
  end
78
107
 
108
+ create_table "skippers", force: true do |t|
109
+ t.string "name"
110
+ t.string "skip_me"
111
+ t.integer "draft_id"
112
+ t.datetime "trashed_at"
113
+ t.datetime "published_at"
114
+ t.datetime "created_at"
115
+ t.datetime "updated_at"
116
+ end
117
+
79
118
  create_table "trashables", force: true do |t|
80
119
  t.string "name"
81
120
  t.string "title"
@@ -0,0 +1,167 @@
1
+ require 'spec_helper'
2
+
3
+ describe Skipper do
4
+ let(:skipper) { Skipper.new :name => 'Bob', :skip_me => 'Skipped 1' }
5
+ it { should be_draftable }
6
+
7
+ describe :draft_creation do
8
+ subject do
9
+ skipper.draft_creation
10
+ skipper.reload
11
+ end
12
+
13
+ it { should be_persisted }
14
+ it { should be_draft }
15
+ its(:draft_id) { should be_present }
16
+ its(:draft) { should be_present }
17
+ its(:draft) { should be_create }
18
+ its(:name) { should eql 'Bob' }
19
+ its(:skip_me) { should eql 'Skipped 1' }
20
+ end
21
+
22
+ describe :draft_update do
23
+ subject do
24
+ skipper.draft_update
25
+ skipper.reload
26
+ end
27
+
28
+ context 'without existing draft' do
29
+ before do
30
+ skipper.save!
31
+ skipper.name = 'Sam'
32
+ skipper.skip_me = 'Skipped 2'
33
+ end
34
+
35
+ it { should be_persisted }
36
+ it { should be_draft }
37
+ its(:draft_id) { should be_present }
38
+ its(:draft) { should be_present }
39
+ its(:draft) { should be_update }
40
+ its(:name) { should eql 'Bob' }
41
+ its(:skip_me) { should eql 'Skipped 2' }
42
+
43
+ it 'creates a new draft' do
44
+ expect { subject }.to change(Draftsman::Draft, :count).by(1)
45
+ end
46
+ end
47
+
48
+ describe 'changing back to initial state' do
49
+ before do
50
+ skipper.published_at = Time.now
51
+ skipper.save!
52
+ skipper.name = 'Sam'
53
+ skipper.draft_update
54
+ skipper.reload
55
+ skipper.name = 'Bob'
56
+ skipper.skip_me = 'Skipped 2'
57
+ end
58
+
59
+ it { should_not be_draft }
60
+ its(:draft_id) { should be_nil }
61
+ its(:draft) { should be_nil }
62
+ its(:name) { should eql 'Bob' }
63
+ its(:skip_me) { should eql 'Skipped 2' }
64
+
65
+ it 'destroys the draft' do
66
+ expect { subject }.to change(Draftsman::Draft.where(:id => skipper.draft_id), :count).by(-1)
67
+ end
68
+ end
69
+
70
+ context 'with existing `create` draft' do
71
+ before { skipper.draft_creation }
72
+
73
+ context 'with changes' do
74
+ before do
75
+ skipper.name = 'Sam'
76
+ skipper.skip_me = 'Skipped 2'
77
+ end
78
+
79
+ it { should be_persisted }
80
+ it { should be_draft }
81
+ its(:draft_id) { should be_present }
82
+ its(:draft) { should be_present }
83
+ its(:draft) { should be_create }
84
+ its(:name) { should eql 'Sam' }
85
+ its(:skip_me) { should eql 'Skipped 2' }
86
+
87
+ it 'updates the existing draft' do
88
+ expect { subject }.to_not change(Draftsman::Draft.where(:id => skipper.draft_id), :count)
89
+ end
90
+
91
+ its "draft's `name` is updated" do
92
+ subject.draft.reify.name.should eql 'Sam'
93
+ end
94
+ end
95
+
96
+ context 'with no changes' do
97
+ it { should be_persisted }
98
+ it { should be_draft }
99
+ its(:draft_id) { should be_present }
100
+ its(:draft) { should be_present }
101
+ its(:draft) { should be_create }
102
+ its(:name) { should eql 'Bob' }
103
+ its(:skip_me) { should eql 'Skipped 1' }
104
+
105
+ it "doesn't change the number of drafts" do
106
+ expect { subject }.to_not change(Draftsman::Draft.where(:id => skipper.draft_id), :count)
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'with existing `update` draft' do
112
+ before do
113
+ skipper.save!
114
+ skipper.name = 'Sam'
115
+ skipper.skip_me = 'Skipped 2'
116
+ skipper.draft_update
117
+ skipper.reload
118
+ skipper.attributes = skipper.draft.reify.attributes
119
+ end
120
+
121
+ context 'with changes' do
122
+ before { skipper.name = 'Steve' }
123
+ it { should be_persisted }
124
+ it { should be_draft }
125
+ its(:draft_id) { should be_present }
126
+ its(:draft) { should be_present }
127
+ its(:draft) { should be_update }
128
+ its(:name) { should eql 'Bob' }
129
+ its(:skip_me) { should eql 'Skipped 2' }
130
+
131
+ it 'updates the existing draft' do
132
+ expect { subject }.to_not change(Draftsman::Draft.where(:id => skipper.draft_id), :count)
133
+ end
134
+
135
+ its "draft's `name` is updated" do
136
+ subject.draft.reify.name.should eql 'Steve'
137
+ end
138
+ end
139
+
140
+ context 'with no changes' do
141
+ it { should be_persisted }
142
+ it { should be_draft }
143
+ its(:draft_id) { should be_present }
144
+ its(:draft) { should be_present }
145
+ its(:draft) { should be_update }
146
+ its(:name) { should eql 'Bob' }
147
+ its(:skip_me) { should eql 'Skipped 2' }
148
+
149
+ it "doesn't change the number of drafts" do
150
+ expect { subject }.to_not change(Draftsman::Draft.where(:id => skipper.draft_id), :count)
151
+ end
152
+
153
+ its "draft's `name` is not updated" do
154
+ subject.draft.reify.name.should eql 'Sam'
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ # Not applicable to this customization
161
+ describe :draft_destroy do
162
+ end
163
+
164
+ # Not applicable to this customization
165
+ describe 'scopes' do
166
+ end
167
+ end
@@ -106,6 +106,8 @@ describe Vanilla do
106
106
  vanilla.save!
107
107
  vanilla.name = 'Sam'
108
108
  vanilla.draft_update
109
+ vanilla.reload
110
+ vanilla.attributes = vanilla.draft.reify.attributes
109
111
  end
110
112
 
111
113
  context 'with changes' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: draftsman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Peters
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-29 00:00:00.000000000 Z
11
+ date: 2014-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -187,6 +187,7 @@ files:
187
187
  - spec/dummy/app/models/bastard.rb
188
188
  - spec/dummy/app/models/child.rb
189
189
  - spec/dummy/app/models/parent.rb
190
+ - spec/dummy/app/models/skipper.rb
190
191
  - spec/dummy/app/models/trashable.rb
191
192
  - spec/dummy/app/models/vanilla.rb
192
193
  - spec/dummy/app/models/whitelister.rb
@@ -221,6 +222,7 @@ files:
221
222
  - spec/models/child_spec.rb
222
223
  - spec/models/draft_spec.rb
223
224
  - spec/models/parent_spec.rb
225
+ - spec/models/skipper_spec.rb
224
226
  - spec/models/trashable_spec.rb
225
227
  - spec/models/vanilla_spec.rb
226
228
  - spec/models/whitelister_spec.rb
@@ -269,6 +271,7 @@ test_files:
269
271
  - spec/dummy/app/models/bastard.rb
270
272
  - spec/dummy/app/models/child.rb
271
273
  - spec/dummy/app/models/parent.rb
274
+ - spec/dummy/app/models/skipper.rb
272
275
  - spec/dummy/app/models/trashable.rb
273
276
  - spec/dummy/app/models/vanilla.rb
274
277
  - spec/dummy/app/models/whitelister.rb
@@ -303,6 +306,7 @@ test_files:
303
306
  - spec/models/child_spec.rb
304
307
  - spec/models/draft_spec.rb
305
308
  - spec/models/parent_spec.rb
309
+ - spec/models/skipper_spec.rb
306
310
  - spec/models/trashable_spec.rb
307
311
  - spec/models/vanilla_spec.rb
308
312
  - spec/models/whitelister_spec.rb