draftsman 0.4.0 → 0.5.0
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/CHANGELOG.md +7 -0
- data/README.md +7 -7
- data/draftsman.gemspec +4 -4
- data/lib/draftsman.rb +23 -0
- data/lib/draftsman/attributes_serialization.rb +89 -0
- data/lib/draftsman/config.rb +10 -0
- data/lib/draftsman/draft.rb +17 -7
- data/lib/draftsman/frameworks/rails.rb +55 -7
- data/lib/draftsman/model.rb +3 -54
- data/lib/draftsman/version.rb +1 -1
- data/spec/controllers/informants_controller_spec.rb +4 -4
- data/spec/controllers/users_controller_spec.rb +4 -4
- data/spec/controllers/whodunnits_controller_spec.rb +7 -7
- data/spec/dummy/app/controllers/application_controller.rb +11 -4
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/environments/test.rb +12 -6
- data/spec/models/trashable_spec.rb +1 -1
- data/spec/models/vanilla_spec.rb +2 -2
- metadata +16 -17
- data/spec/support/silence_serialized_attributes_deprecation.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f18e08326633f6b3b20b26217a23d1d81042d158
|
4
|
+
data.tar.gz: 4d0ab78461094ab35bc1d4b77322a88237eed9a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8a87e165dcaf68c72f65a97471c418e4bde43de5c07da002ab47b13ec9067e52744bf25b6909ba74199765d61a8619b779692e8f88ece0a910af182cae2bcd9
|
7
|
+
data.tar.gz: d28d6bf39bc7c4e7ef5ea2891445529687eddb54142dc79bc9c5f676273923c3b85f8865c9429698e62b6d23f540bdc1d429567c7365b381adaa269203eea43f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.5.0 - August 20, 2016
|
4
|
+
|
5
|
+
- [@npezza93](https://github.com/npezza93)
|
6
|
+
[Implemented](https://github.com/liveeditor/draftsman/pull/45)
|
7
|
+
[#44](https://github.com/liveeditor/draftsman/issues/44)
|
8
|
+
Rails 5 compatibility
|
9
|
+
|
3
10
|
## 0.4.0 - April 5, 2016
|
4
11
|
|
5
12
|
- [@npafundi](https://github.com/npafundi)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Draftsman v0.
|
1
|
+
# Draftsman v0.5.0 (beta)
|
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.
|
@@ -41,18 +41,18 @@ source: it's a nice clean example of a gem that hooks into Rails and Sinatra.
|
|
41
41
|
|
42
42
|
## Compatibility
|
43
43
|
|
44
|
-
Compatible with ActiveRecord 3 and
|
44
|
+
Compatible with ActiveRecord 3, 4, and 5.
|
45
45
|
|
46
46
|
Works well with Rails, Sinatra, or any other application that depends on ActiveRecord.
|
47
47
|
|
48
48
|
## Installation
|
49
49
|
|
50
|
-
### Rails 3
|
50
|
+
### Rails 3, 4, and 5
|
51
51
|
|
52
52
|
Add Draftsman to your `Gemfile`.
|
53
53
|
|
54
54
|
```ruby
|
55
|
-
gem 'draftsman', '~> 0.
|
55
|
+
gem 'draftsman', '~> 0.5.0'
|
56
56
|
```
|
57
57
|
|
58
58
|
Or if you want to grab the latest from `master`:
|
@@ -323,8 +323,8 @@ this. It also presents all data in its drafted form, if a draft exists.
|
|
323
323
|
|
324
324
|
```ruby
|
325
325
|
class Admin::WidgetsController < Admin::BaseController
|
326
|
-
|
327
|
-
|
326
|
+
before_action :find_widget, :only => [:show, :edit, :update, :destroy]
|
327
|
+
before_action :reify_widget, :only => [:show, :edit]
|
328
328
|
|
329
329
|
def index
|
330
330
|
# The `live` scope gives us widgets that aren't in the trash.
|
@@ -423,7 +423,7 @@ other workflow action that you would like for your application to provide for dr
|
|
423
423
|
|
424
424
|
```ruby
|
425
425
|
class Admin::DraftsController < Admin::BaseController
|
426
|
-
|
426
|
+
before_action :find_draft, :only => [:show, :update, :destroy]
|
427
427
|
|
428
428
|
def index
|
429
429
|
@drafts = Draftsman::Draft.includes(:item).order('updated_at DESC')
|
data/draftsman.gemspec
CHANGED
@@ -16,12 +16,12 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
s.require_paths = ['lib']
|
18
18
|
|
19
|
-
s.add_dependency 'activerecord', ['>= 3.0', '< 5.
|
19
|
+
s.add_dependency 'activerecord', ['>= 3.0', '< 5.1']
|
20
20
|
|
21
|
-
s.add_development_dependency 'rake'
|
22
|
-
s.add_development_dependency 'railties', ['>= 3.0', '< 5.
|
21
|
+
s.add_development_dependency 'rake'
|
22
|
+
s.add_development_dependency 'railties', ['>= 3.0', '< 5.1']
|
23
23
|
s.add_development_dependency 'sinatra', '~> 1.0'
|
24
|
-
s.add_development_dependency 'rspec-rails', '3.
|
24
|
+
s.add_development_dependency 'rspec-rails', '~> 3.5'
|
25
25
|
|
26
26
|
# JRuby support for the test ENV
|
27
27
|
if defined?(JRUBY_VERSION)
|
data/lib/draftsman.rb
CHANGED
@@ -7,6 +7,29 @@ Dir[File.join(File.dirname(__FILE__), 'draftsman', 'serializers', '*.rb')].each
|
|
7
7
|
|
8
8
|
# Draftsman's module methods can be called in both models and controllers.
|
9
9
|
module Draftsman
|
10
|
+
# Switches Draftsman on or off.
|
11
|
+
def self.enabled=(value)
|
12
|
+
Draftsman.config.enabled = value
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns `true` if Draftsman is on, `false` otherwise.
|
16
|
+
# Draftsman is enabled by default.
|
17
|
+
def self.enabled?
|
18
|
+
!!Draftsman.config.enabled
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets whether Draftsman is enabled or disabled for the current request.
|
22
|
+
def self.enabled_for_controller=(value)
|
23
|
+
draftsman_store[:request_enabled_for_controller] = value
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns `true` if Draftsman is enabled for the request, `false` otherwise.
|
27
|
+
#
|
28
|
+
# See `Draftsman::Rails::Controller#draftsman_enabled_for_controller`.
|
29
|
+
def self.enabled_for_controller?
|
30
|
+
!!draftsman_store[:request_enabled_for_controller]
|
31
|
+
end
|
32
|
+
|
10
33
|
# Returns whether or not ActiveRecord is configured to require mass assignment whitelisting via `attr_accessible`.
|
11
34
|
def self.active_record_protected_attributes?
|
12
35
|
@active_record_protected_attributes ||= ActiveRecord::VERSION::STRING.to_f < 4.0 || defined?(ProtectedAttributes)
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Draftsman
|
2
|
+
module AttributesSerialization
|
3
|
+
class NoOpAttribute
|
4
|
+
def type_cast_for_database(value)
|
5
|
+
value
|
6
|
+
end
|
7
|
+
|
8
|
+
def type_cast_from_database(data)
|
9
|
+
data
|
10
|
+
end
|
11
|
+
end
|
12
|
+
NO_OP_ATTRIBUTE = NoOpAttribute.new
|
13
|
+
|
14
|
+
class SerializedAttribute
|
15
|
+
def initialize(coder)
|
16
|
+
@coder = coder.respond_to?(:dump) ? coder : Draftsman.serializer
|
17
|
+
end
|
18
|
+
|
19
|
+
def type_cast_for_database(value)
|
20
|
+
@coder.dump(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def type_cast_from_database(data)
|
24
|
+
@coder.load(data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
SERIALIZE, DESERIALIZE =
|
29
|
+
if ::ActiveRecord::VERSION::MAJOR >= 5
|
30
|
+
[:serialize, :deserialize]
|
31
|
+
else
|
32
|
+
[:type_cast_for_database, :type_cast_from_database]
|
33
|
+
end
|
34
|
+
|
35
|
+
if ::ActiveRecord::VERSION::STRING < '4.2'
|
36
|
+
# Backport Rails 4.2 and later's `type_for_attribute` to build
|
37
|
+
# on a common interface.
|
38
|
+
def type_for_attribute(attr_name)
|
39
|
+
serialized_attribute_types[attr_name.to_s] || NO_OP_ATTRIBUTE
|
40
|
+
end
|
41
|
+
|
42
|
+
def serialized_attribute_types
|
43
|
+
@attribute_types ||= Hash[serialized_attributes.map do |attr_name, coder|
|
44
|
+
[attr_name, SerializedAttribute.new(coder)]
|
45
|
+
end]
|
46
|
+
end
|
47
|
+
private :serialized_attribute_types
|
48
|
+
end
|
49
|
+
|
50
|
+
# Used for `Version#object` attribute.
|
51
|
+
def serialize_attributes_for_draftsman(attributes)
|
52
|
+
alter_attributes_for_draftsman(SERIALIZE, attributes)
|
53
|
+
end
|
54
|
+
|
55
|
+
def unserialize_attributes_for_draftsman(attributes)
|
56
|
+
alter_attributes_for_draftsman(DESERIALIZE, attributes)
|
57
|
+
end
|
58
|
+
|
59
|
+
def alter_attributes_for_draftsman(serializer, attributes)
|
60
|
+
# Don't serialize before values before inserting into columns of type
|
61
|
+
# `JSON` on `PostgreSQL` databases.
|
62
|
+
return attributes if self.draft_class.object_col_is_json?
|
63
|
+
|
64
|
+
attributes.each do |key, value|
|
65
|
+
attributes[key] = type_for_attribute(key).send(serializer, value)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Used for Version#object_changes attribute.
|
70
|
+
def serialize_draft_attribute_changes(changes)
|
71
|
+
alter_draft_attribute_changes(SERIALIZE, changes)
|
72
|
+
end
|
73
|
+
|
74
|
+
def unserialize_draft_attribute_changes(changes)
|
75
|
+
alter_draft_attribute_changes(DESERIALIZE, changes)
|
76
|
+
end
|
77
|
+
|
78
|
+
def alter_draft_attribute_changes(serializer, changes)
|
79
|
+
# Don't serialize before values before inserting into columns of type
|
80
|
+
# `JSON` on `PostgreSQL` databases.
|
81
|
+
return changes if self.draft_class.object_changes_col_is_json?
|
82
|
+
|
83
|
+
changes.clone.each do |key, change|
|
84
|
+
type = type_for_attribute(key)
|
85
|
+
changes[key] = Array(change).map { |value| type.send(serializer, value) }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/draftsman/config.rb
CHANGED
@@ -7,7 +7,17 @@ module Draftsman
|
|
7
7
|
|
8
8
|
def initialize
|
9
9
|
@timestamp_field = :created_at
|
10
|
+
@mutex = Mutex.new
|
10
11
|
@serializer = Draftsman::Serializers::Yaml
|
11
12
|
end
|
13
|
+
|
14
|
+
# Indicates whether Draftsman is on or off. Default: true.
|
15
|
+
def enabled
|
16
|
+
@mutex.synchronize { !!@enabled }
|
17
|
+
end
|
18
|
+
|
19
|
+
def enabled=(enable)
|
20
|
+
@mutex.synchronize { @enabled = enable }
|
21
|
+
end
|
12
22
|
end
|
13
23
|
end
|
data/lib/draftsman/draft.rb
CHANGED
@@ -46,13 +46,7 @@ class Draftsman::Draft < ActiveRecord::Base
|
|
46
46
|
def changeset
|
47
47
|
return nil unless self.class.column_names.include? 'object_changes'
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
@changeset ||= HashWithIndifferentAccess.new(_changes).tap do |changes|
|
52
|
-
item_type.constantize.unserialize_draft_attribute_changes(changes)
|
53
|
-
end
|
54
|
-
rescue
|
55
|
-
{}
|
49
|
+
@changeset ||= load_changeset
|
56
50
|
end
|
57
51
|
|
58
52
|
# Returns whether or not this is a `create` event.
|
@@ -303,4 +297,20 @@ private
|
|
303
297
|
block.call
|
304
298
|
end
|
305
299
|
end
|
300
|
+
|
301
|
+
def load_changeset
|
302
|
+
changes = HashWithIndifferentAccess.new(object_changes_deserialized)
|
303
|
+
item_type.constantize.unserialize_draft_attribute_changes(changes)
|
304
|
+
changes
|
305
|
+
rescue
|
306
|
+
{}
|
307
|
+
end
|
308
|
+
|
309
|
+
def object_changes_deserialized
|
310
|
+
if self.class.object_changes_col_is_json?
|
311
|
+
object_changes
|
312
|
+
else
|
313
|
+
Draftsman.serializer.load(object_changes)
|
314
|
+
end
|
315
|
+
end
|
306
316
|
end
|
@@ -1,9 +1,23 @@
|
|
1
1
|
module Draftsman
|
2
2
|
module Rails
|
3
3
|
module Controller
|
4
|
-
|
5
4
|
def self.included(base)
|
6
|
-
|
5
|
+
before = [
|
6
|
+
:set_draftsman_enabled_for_controller,
|
7
|
+
:set_draftsman_controller_info
|
8
|
+
]
|
9
|
+
after = [
|
10
|
+
:warn_about_not_setting_whodunnit
|
11
|
+
]
|
12
|
+
if base.respond_to? :before_action
|
13
|
+
# Rails 4+
|
14
|
+
before.map { |sym| base.before_action sym }
|
15
|
+
after.map { |sym| base.after_action sym }
|
16
|
+
else
|
17
|
+
# Rails 3.
|
18
|
+
before.map { |sym| base.before_filter sym }
|
19
|
+
after.map { |sym| base.after_filter sym }
|
20
|
+
end
|
7
21
|
end
|
8
22
|
|
9
23
|
protected
|
@@ -14,7 +28,10 @@ module Draftsman
|
|
14
28
|
# Override this method in your controller to call a different
|
15
29
|
# method, e.g. `current_person`, or anything you like.
|
16
30
|
def user_for_draftsman
|
17
|
-
|
31
|
+
return unless defined?(current_user)
|
32
|
+
ActiveSupport::VERSION::MAJOR >= 4 ? current_user.try!(:id) : current_user.try(:id)
|
33
|
+
rescue NoMethodError
|
34
|
+
current_user
|
18
35
|
end
|
19
36
|
|
20
37
|
# Returns any information about the controller or request that you
|
@@ -38,23 +55,54 @@ module Draftsman
|
|
38
55
|
{}
|
39
56
|
end
|
40
57
|
|
58
|
+
# Returns `true` (default) or `false` depending on whether Draftsman
|
59
|
+
# should be active for the current request.
|
60
|
+
#
|
61
|
+
# Override this method in your controller to specify when Draftsman
|
62
|
+
# should be off.
|
63
|
+
def draftsman_enabled_for_controller
|
64
|
+
::Draftsman.enabled?
|
65
|
+
end
|
66
|
+
|
41
67
|
private
|
42
68
|
|
69
|
+
# Tells Draftsman whether drafts should be saved in the current request.
|
70
|
+
def set_draftsman_enabled_for_controller
|
71
|
+
::Draftsman.enabled_for_controller = draftsman_enabled_for_controller
|
72
|
+
end
|
73
|
+
|
43
74
|
# Tells Draftsman who is responsible for any changes that occur.
|
44
75
|
def set_draftsman_whodunnit
|
45
|
-
|
76
|
+
@set_draftsman_whodunnit_called = true
|
77
|
+
::Draftsman.whodunnit = user_for_draftsman if ::Draftsman.enabled_for_controller?
|
46
78
|
end
|
47
79
|
|
48
|
-
# Tells Draftsman any information from the controller you want
|
49
|
-
#
|
80
|
+
# Tells Draftsman any information from the controller you want to store
|
81
|
+
# alongside any changes that occur.
|
50
82
|
def set_draftsman_controller_info
|
51
83
|
::Draftsman.controller_info = info_for_draftsman
|
52
84
|
end
|
53
85
|
|
86
|
+
def warn_about_not_setting_whodunnit
|
87
|
+
enabled = ::Draftsman.enabled_for_controller?
|
88
|
+
user_present = user_for_draftsman.present?
|
89
|
+
whodunnit_blank = ::Draftsman.whodunnit.blank?
|
90
|
+
if enabled && user_present && whodunnit_blank && !@set_draftsman_whodunnit_called
|
91
|
+
::Kernel.warn <<-EOS.strip_heredoc
|
92
|
+
user_for_draftsman is present, but whodunnit has not been set.
|
93
|
+
Draftsman no longer adds the set_draftsman_whodunnit callback for
|
94
|
+
you. To continue recording whodunnit, please add this before_action
|
95
|
+
callback to your ApplicationController . For more information,
|
96
|
+
please see https://git.io/vrTsk
|
97
|
+
EOS
|
98
|
+
end
|
99
|
+
end
|
54
100
|
end
|
55
101
|
end
|
56
102
|
|
57
103
|
if defined?(::ActionController)
|
58
|
-
::ActiveSupport.on_load(:action_controller)
|
104
|
+
::ActiveSupport.on_load(:action_controller) do
|
105
|
+
include ::Draftsman::Rails::Controller
|
106
|
+
end
|
59
107
|
end
|
60
108
|
end
|
data/lib/draftsman/model.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'draftsman/attributes_serialization'
|
2
|
+
|
1
3
|
module Draftsman
|
2
4
|
module Model
|
3
5
|
|
@@ -44,6 +46,7 @@ module Draftsman
|
|
44
46
|
# Lazily include the instance methods so we don't clutter up
|
45
47
|
# any more ActiveRecord models than we need to.
|
46
48
|
send :include, InstanceMethods
|
49
|
+
send :extend, AttributesSerialization
|
47
50
|
|
48
51
|
# Define before/around/after callbacks on each drafted model
|
49
52
|
send :extend, ActiveModel::Callbacks
|
@@ -124,65 +127,11 @@ module Draftsman
|
|
124
127
|
method_defined?(:draftsman_options)
|
125
128
|
end
|
126
129
|
|
127
|
-
# Serializes attribute changes for `Draft#object_changes` attribute.
|
128
|
-
def serialize_draft_attribute_changes(changes)
|
129
|
-
# Don't serialize values before inserting into columns of type `JSON` on PostgreSQL databases.
|
130
|
-
return changes if self.draft_class.object_changes_col_is_json?
|
131
|
-
|
132
|
-
serialized_attributes.each do |key, coder|
|
133
|
-
if changes.key?(key)
|
134
|
-
coder = Draftsman::Serializers::Yaml unless coder.respond_to?(:dump) # Fall back to YAML if `coder` has no `dump` method
|
135
|
-
old_value, new_value = changes[key]
|
136
|
-
changes[key] = [coder.dump(old_value), coder.dump(new_value)]
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Used for `Draft#object` attribute
|
142
|
-
def serialize_attributes_for_draftsman(attributes)
|
143
|
-
# Don't serialize values before inserting into columns of type `JSON` on PostgreSQL databases.
|
144
|
-
return attributes if self.draft_class.object_col_is_json?
|
145
|
-
|
146
|
-
serialized_attributes.each do |key, coder|
|
147
|
-
if attributes.key?(key)
|
148
|
-
coder = Draftsman::Serializers::Yaml unless coder.respond_to?(:dump) # Fall back to YAML if `coder` has no `dump` method
|
149
|
-
attributes[key] = coder.dump(attributes[key])
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
130
|
# Returns whether or not a `trashed_at` timestamp is set up on this model.
|
155
131
|
def trashable?
|
156
132
|
draftable? && method_defined?(self.trashed_at_attribute_name)
|
157
133
|
end
|
158
134
|
|
159
|
-
# Unserializes attribute changes for `Draft#object_changes` attribute.
|
160
|
-
def unserialize_draft_attribute_changes(changes)
|
161
|
-
# Don't serialize values before inserting into columns of type `JSON` on PostgreSQL databases.
|
162
|
-
return changes if self.draft_class.object_changes_col_is_json?
|
163
|
-
|
164
|
-
serialized_attributes.each do |key, coder|
|
165
|
-
if changes.key?(key)
|
166
|
-
coder = Draftsman::Serializers::Yaml unless coder.respond_to?(:dump)
|
167
|
-
old_value, new_value = changes[key]
|
168
|
-
changes[key] = [coder.load(old_value), coder.load(new_value)]
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
# Used for `Draft#object` attribute
|
174
|
-
def unserialize_attributes_for_draftsman(attributes)
|
175
|
-
# Don't serialize values before inserting into columns of type `JSON` on PostgreSQL databases.
|
176
|
-
return attributes if self.draft_class.object_col_is_json?
|
177
|
-
|
178
|
-
serialized_attributes.each do |key, coder|
|
179
|
-
if attributes.key?(key)
|
180
|
-
coder = Draftsman::Serializers::Yaml unless coder.respond_to?(:dump)
|
181
|
-
attributes[key] = coder.load(attributes[key])
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
135
|
# Returns whether or not the included ActiveRecord can do `where.not(...)` style queries.
|
187
136
|
def where_not?
|
188
137
|
ActiveRecord::VERSION::STRING.to_f >= 4.0
|
data/lib/draftsman/version.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
# Tests controller `info_for_draftsman` method
|
4
|
-
describe InformantsController, :
|
5
|
-
let(:trashable) { Trashable.create!(:
|
4
|
+
describe InformantsController, type: :controller do
|
5
|
+
let(:trashable) { Trashable.create!(name: 'Bob') }
|
6
6
|
|
7
7
|
describe 'create' do
|
8
8
|
before { post :create }
|
@@ -18,7 +18,7 @@ describe InformantsController, :type => :controller do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe 'update' do
|
21
|
-
before { put :update, :
|
21
|
+
before { put :update, id: trashable.id }
|
22
22
|
subject { Draftsman::Draft.last }
|
23
23
|
|
24
24
|
it 'records `ip` from custom `info_for_draftsman`' do
|
@@ -31,7 +31,7 @@ describe InformantsController, :type => :controller do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe 'destroy' do
|
34
|
-
before { delete :destroy, :
|
34
|
+
before { delete :destroy, id: trashable.id }
|
35
35
|
subject { Draftsman::Draft.last }
|
36
36
|
|
37
37
|
it 'records `ip` from custom `info_for_draftsman`' do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe UsersController, :
|
4
|
-
let(:trashable) { Trashable.create!(:
|
3
|
+
describe UsersController, type: :controller do
|
4
|
+
let(:trashable) { Trashable.create!(name: 'Bob') }
|
5
5
|
|
6
6
|
describe 'create' do
|
7
7
|
before { post :create }
|
@@ -13,7 +13,7 @@ describe UsersController, :type => :controller do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe 'update' do
|
16
|
-
before { put :update, :
|
16
|
+
before { put :update, id: trashable.id }
|
17
17
|
subject { return Draftsman::Draft.last }
|
18
18
|
|
19
19
|
it 'records user name via `user_for_draftsman`' do
|
@@ -22,7 +22,7 @@ describe UsersController, :type => :controller do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
describe 'destroy' do
|
25
|
-
before { delete :destroy, :
|
25
|
+
before { delete :destroy, id: trashable.id }
|
26
26
|
subject { return Draftsman::Draft.last }
|
27
27
|
|
28
28
|
it 'records user name via `user_for_draftsman`' do
|
@@ -1,33 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
# Tests the automatic usage of `current_user` as the `whodunnit` attribute on the draft object
|
4
|
-
describe WhodunnitsController, :
|
5
|
-
let(:trashable) { Trashable.create!(:
|
4
|
+
describe WhodunnitsController, type: :controller do
|
5
|
+
let(:trashable) { Trashable.create!(name: 'Bob') }
|
6
6
|
|
7
7
|
describe 'create' do
|
8
8
|
before { post :create }
|
9
9
|
subject { Draftsman::Draft.last }
|
10
10
|
|
11
11
|
it 'records `current_user` via `user_for_draftsman' do
|
12
|
-
expect(subject.whodunnit).to eql
|
12
|
+
expect(subject.whodunnit).to eql '153'
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
describe 'update' do
|
17
|
-
before { put :update, :
|
17
|
+
before { put :update, id: trashable.id }
|
18
18
|
subject { Draftsman::Draft.last }
|
19
19
|
|
20
20
|
it 'records `current_user` via `user_for_draftsman' do
|
21
|
-
expect(subject.whodunnit).to eql
|
21
|
+
expect(subject.whodunnit).to eql '153'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe 'destroy' do
|
26
|
-
before { delete :destroy, :
|
26
|
+
before { delete :destroy, id: trashable.id }
|
27
27
|
subject { Draftsman::Draft.last }
|
28
28
|
|
29
29
|
it 'records `current_user` via `user_for_draftsman' do
|
30
|
-
expect(subject.whodunnit).to eql
|
30
|
+
expect(subject.whodunnit).to eql '153'
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,20 +1,27 @@
|
|
1
1
|
class ApplicationController < ActionController::Base
|
2
2
|
protect_from_forgery
|
3
|
+
before_action :set_draftsman_whodunnit
|
3
4
|
|
4
5
|
def create
|
5
|
-
Trashable.new(:
|
6
|
-
|
6
|
+
Trashable.new(name: 'Bob').draft_creation
|
7
|
+
head :no_content
|
7
8
|
end
|
8
9
|
|
9
10
|
def update
|
10
11
|
trashable = Trashable.last
|
11
12
|
trashable.name = 'Sam'
|
12
13
|
trashable.draft_update
|
13
|
-
|
14
|
+
head :no_content
|
14
15
|
end
|
15
16
|
|
16
17
|
def destroy
|
17
18
|
Trashable.last.draft_destruction
|
18
|
-
|
19
|
+
head :no_content
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def draftsman_enabled_for_controller
|
25
|
+
request.user_agent != 'Disable User-Agent'
|
19
26
|
end
|
20
27
|
end
|
@@ -32,6 +32,6 @@ module Dummy
|
|
32
32
|
config.active_record.whitelist_attributes = false if ::Draftsman.active_record_protected_attributes?
|
33
33
|
|
34
34
|
# Do not access the DB or load models when precompiling assets
|
35
|
-
config.assets.
|
35
|
+
config.assets.enabled = false if config.respond_to?(:assets)
|
36
36
|
end
|
37
37
|
end
|
@@ -12,15 +12,21 @@ Dummy::Application.configure do
|
|
12
12
|
# preloads Rails for running tests, you may have to set it to true.
|
13
13
|
config.eager_load = false
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
if config.respond_to?(:public_file_server)
|
16
|
+
config.public_file_server.enabled = true
|
17
|
+
elsif config.respond_to?(:serve_static_files=)
|
18
|
+
config.serve_static_files = true
|
19
19
|
else
|
20
|
-
config.
|
20
|
+
config.serve_static_assets = true
|
21
21
|
end
|
22
22
|
|
23
|
-
config.
|
23
|
+
if config.respond_to?(:public_file_server)
|
24
|
+
config.public_file_server.headers = {
|
25
|
+
"Cache-Control" => "public, max-age=3600"
|
26
|
+
}
|
27
|
+
else
|
28
|
+
config.static_cache_control = "public, max-age=3600"
|
29
|
+
end
|
24
30
|
|
25
31
|
# Show full error reports and disable caching
|
26
32
|
config.consider_all_requests_local = true
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
# A Trashable has a simple call to `has_drafts` without any options specified. The model also contains a `deleted_at`
|
4
4
|
# attribute, which allows deletes to be drafts too.
|
5
5
|
describe Trashable do
|
6
|
-
let(:trashable) { Trashable.new :
|
6
|
+
let(:trashable) { Trashable.new name: 'Bob' }
|
7
7
|
|
8
8
|
describe '.draftable?' do
|
9
9
|
it 'is draftable' do
|
data/spec/models/vanilla_spec.rb
CHANGED
@@ -287,7 +287,7 @@ describe Vanilla do
|
|
287
287
|
subject { Vanilla.live }
|
288
288
|
|
289
289
|
it 'raises an exception' do
|
290
|
-
expect { subject.load }.to raise_exception
|
290
|
+
expect { subject.load }.to raise_exception(ActiveRecord::StatementInvalid)
|
291
291
|
end
|
292
292
|
end
|
293
293
|
|
@@ -311,7 +311,7 @@ describe Vanilla do
|
|
311
311
|
subject { Vanilla.trashed }
|
312
312
|
|
313
313
|
it 'raises an exception' do
|
314
|
-
expect { subject.load }.to raise_exception
|
314
|
+
expect { subject.load }.to raise_exception(ActiveRecord::StatementInvalid)
|
315
315
|
end
|
316
316
|
end
|
317
317
|
end
|
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.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Peters
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '3.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '5.
|
22
|
+
version: '5.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,21 +29,21 @@ dependencies:
|
|
29
29
|
version: '3.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5.
|
32
|
+
version: '5.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - "
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '0'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: railties
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
version: '3.0'
|
54
54
|
- - "<"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '5.
|
56
|
+
version: '5.1'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -63,7 +63,7 @@ dependencies:
|
|
63
63
|
version: '3.0'
|
64
64
|
- - "<"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '5.
|
66
|
+
version: '5.1'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: sinatra
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,16 +82,16 @@ dependencies:
|
|
82
82
|
name: rspec-rails
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
|
-
- -
|
85
|
+
- - "~>"
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: 3.
|
87
|
+
version: '3.5'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
90
|
version_requirements: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
|
-
- -
|
92
|
+
- - "~>"
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version: 3.
|
94
|
+
version: '3.5'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
name: sqlite3
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- Rakefile
|
123
123
|
- draftsman.gemspec
|
124
124
|
- lib/draftsman.rb
|
125
|
+
- lib/draftsman/attributes_serialization.rb
|
125
126
|
- lib/draftsman/config.rb
|
126
127
|
- lib/draftsman/draft.rb
|
127
128
|
- lib/draftsman/frameworks/cucumber.rb
|
@@ -204,7 +205,6 @@ files:
|
|
204
205
|
- spec/models/vanilla_spec.rb
|
205
206
|
- spec/models/whitelister_spec.rb
|
206
207
|
- spec/spec_helper.rb
|
207
|
-
- spec/support/silence_serialized_attributes_deprecation.rb
|
208
208
|
homepage: https://github.com/liveeditor/draftsman
|
209
209
|
licenses:
|
210
210
|
- MIT
|
@@ -225,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
225
|
version: '0'
|
226
226
|
requirements: []
|
227
227
|
rubyforge_project:
|
228
|
-
rubygems_version: 2.
|
228
|
+
rubygems_version: 2.5.1
|
229
229
|
signing_key:
|
230
230
|
specification_version: 4
|
231
231
|
summary: Create draft versions of your database records.
|
@@ -296,4 +296,3 @@ test_files:
|
|
296
296
|
- spec/models/vanilla_spec.rb
|
297
297
|
- spec/models/whitelister_spec.rb
|
298
298
|
- spec/spec_helper.rb
|
299
|
-
- spec/support/silence_serialized_attributes_deprecation.rb
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# SerializedAttributes is deprecated in Rails 4.2.x, and will be removed in
|
2
|
-
# Rails 5. Draftsman spews a ton of deprecation warnings about this issue.
|
3
|
-
#
|
4
|
-
# More info: https://github.com/airblade/paper_trail/issues/416
|
5
|
-
#
|
6
|
-
# TODO: when migrating to Rails 5, remove this initializer
|
7
|
-
|
8
|
-
if Draftsman::VERSION.to_f < 1.0
|
9
|
-
current_behavior = ActiveSupport::Deprecation.behavior
|
10
|
-
ActiveSupport::Deprecation.behavior = lambda do |message, callstack|
|
11
|
-
return if message =~ /`serialized_attributes` is deprecated without replacement/ && callstack.any? { |m| m =~ /draftsman/ }
|
12
|
-
Array.wrap(current_behavior).each { |behavior| behavior.call(message, callstack) }
|
13
|
-
end
|
14
|
-
else
|
15
|
-
warn 'FIXME: Draftsman initializer to suppress deprecation warnings can be safely removed.'
|
16
|
-
end
|