kentouzu 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +1 -1
- data/kentouzu.gemspec +5 -8
- data/lib/generators/kentouzu/install_generator.rb +0 -1
- data/lib/kentouzu/controller.rb +4 -4
- data/lib/kentouzu/draft.rb +83 -27
- data/lib/kentouzu/has_drafts.rb +126 -38
- data/lib/kentouzu/version.rb +1 -1
- data/lib/kentouzu.rb +47 -1
- metadata +33 -62
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b39f53d72a27a2ab22bc2d2ac95627e62ca349c5
|
4
|
+
data.tar.gz: 075eee3f632a1a30b30b7ba06f4d36e9ba4da7f9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1c4405b4bf4d4997fd1ec9195ea3ef9bc7df25e30e3ef7f7501cfa92646a5d107a8dda00a12c92bf789c648c6d45a1076d8b0e67dddb7af1b2015cc2ca07336
|
7
|
+
data.tar.gz: fce154503e796c800a21b5186fac0deab7d89b2f8a357696d745258314bbe2493b95d57126b641f417b79ff12d5c8db82d125efec580bdb10d4b4c71b0a25664
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
2.1.3
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
+
## v0.2.0
|
2
|
+
|
3
|
+
* Breaking changes to the way objects are serialized and deserialized.
|
4
|
+
* `has_many` associations are now serialized along with the object.
|
5
|
+
* Deprecated `drafts_on` and `drafts_off` in favor of `drafts_on!` and `drafts_off!`.
|
6
|
+
* Added `Kentouzu.enabled_for_model` and `Kentouzu.enabled_for_model?`.
|
7
|
+
* Added `Kentouzu.active_record_protected_attributes?` to enable handling of attr_accessible.
|
8
|
+
* Attempt to load `protected_attributes` gem if it's available.
|
9
|
+
* Added `Draft.with_source_keys`.
|
10
|
+
* Deprecated `Draft#approve` and `Draft#reject`.
|
11
|
+
* Added override for `save!`.
|
12
|
+
|
1
13
|
## v0.1.2
|
2
14
|
|
3
15
|
* Added callbacks for `before_draft_save`, `after_draft_save`, and `around_draft_save`.
|
16
|
+
* Fixed a bug where invalid attributes were merged from controller options when saving a draft.
|
4
17
|
|
5
18
|
## v0.1.1
|
6
19
|
|
data/Gemfile.lock
CHANGED
data/kentouzu.gemspec
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
|
2
|
-
$:.push File.expand_path('../lib', __FILE__)
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
3
2
|
require 'kentouzu/version'
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = 'kentouzu'
|
7
6
|
s.version = Kentouzu::VERSION
|
8
|
-
s.authors = ['Sean Eshbaugh']
|
9
|
-
s.email = ['seaneshbaugh@gmail.com']
|
10
|
-
s.homepage = 'https://github.com/seaneshbaugh/kentouzu'
|
11
7
|
s.summary = 'Add drafts to ActiveRecord models.'
|
12
|
-
s.description =
|
13
|
-
|
14
|
-
s.
|
8
|
+
s.description = s.summary
|
9
|
+
s.homepage = 'https://github.com/seaneshbaugh/kentouzu'
|
10
|
+
s.authors = ['Sean Eshbaugh']
|
11
|
+
s.email = 'seaneshbaugh@gmail.com'
|
15
12
|
|
16
13
|
s.files = `git ls-files`.split("\n")
|
17
14
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/kentouzu/controller.rb
CHANGED
@@ -17,21 +17,21 @@ module Kentouzu
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def drafts_enabled_for_controller
|
20
|
-
|
20
|
+
Kentouzu.enabled?
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def set_drafts_source
|
26
|
-
|
26
|
+
Kentouzu.source = user_for_drafts
|
27
27
|
end
|
28
28
|
|
29
29
|
def set_drafts_controller_info
|
30
|
-
|
30
|
+
Kentouzu.controller_info = info_for_drafts
|
31
31
|
end
|
32
32
|
|
33
33
|
def set_drafts_enabled_for_controller
|
34
|
-
|
34
|
+
Kentouzu.enabled_for_controller = drafts_enabled_for_controller
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/kentouzu/draft.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
class Draft < ActiveRecord::Base
|
2
|
+
if Kentouzu.active_record_protected_attributes?
|
3
|
+
attr_accessible :item_type, :item_id, :event, :source_type, :source_id, :object
|
4
|
+
end
|
5
|
+
|
2
6
|
belongs_to :item, :polymorphic => true
|
3
7
|
|
4
8
|
belongs_to :source, :polymorphic => true
|
@@ -6,7 +10,11 @@ class Draft < ActiveRecord::Base
|
|
6
10
|
validates_presence_of :event
|
7
11
|
|
8
12
|
def self.with_item_keys(item_type, item_id)
|
9
|
-
|
13
|
+
where :item_type => item_type, :item_id => item_id
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.with_source_keys(source_type, source_id)
|
17
|
+
where :source_type => source_type, :source_id => source_id
|
10
18
|
end
|
11
19
|
|
12
20
|
def self.creates
|
@@ -17,57 +25,97 @@ class Draft < ActiveRecord::Base
|
|
17
25
|
where :event => 'update'
|
18
26
|
end
|
19
27
|
|
20
|
-
|
28
|
+
def subsequent(obj, timestamp_arg = false)
|
29
|
+
if timestamp_arg != true && self.primary_key_is_int?
|
30
|
+
where(arel_table[primary_key].gt(obj.id)).order(arel_table[primary_key].asc)
|
31
|
+
else
|
32
|
+
obj = obj.send(Kentouzu.timestamp_field) if obj.is_a?(self)
|
21
33
|
|
22
|
-
|
34
|
+
where(arel_table[Kentouzu.timestamp_field].gt(obj)).order(self.timestamp_sort_order)
|
35
|
+
end
|
36
|
+
end
|
23
37
|
|
24
|
-
|
38
|
+
def preceding(obj, timestamp_arg = false)
|
39
|
+
if timestamp_arg != true && self.primary_key_is_int?
|
40
|
+
where(arel_table[primary_key].lt(obj.id)).order(arel_table[primary_key].asc)
|
41
|
+
else
|
42
|
+
obj = obj.send(Kentouzu.timestamp_field) if obj.is_a?(self)
|
25
43
|
|
26
|
-
|
44
|
+
where(arel_table[Kentouzu.timestamp_field].lt(obj)).order(self.timestamp_sort_order)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def following(timestamp)
|
49
|
+
where(arel_table[Kentouzu.timestamp_field].gt(timestamp)).order(self.timestamp_sort_order)
|
50
|
+
end
|
51
|
+
|
52
|
+
def between(start_time, end_time)
|
53
|
+
where(arel_tabl[Kentouzu.timestamp_field].gt(start_time).and(arel_table[Kentouzu.timestamp_field].lt(end_time))).order(self.timestamp_sort_order)
|
54
|
+
end
|
55
|
+
|
56
|
+
def timestamp_sort_order(direction = 'asc')
|
57
|
+
[arel_table[Kentouzu.timestamp_field].send(direction.downcase)].tap do |array|
|
58
|
+
array << arel_table[primary_key].send(direction.downcase) if self.primary_key_is_int?
|
59
|
+
end
|
60
|
+
end
|
27
61
|
|
62
|
+
# Restore the item from this draft.
|
63
|
+
#
|
64
|
+
# Options:
|
65
|
+
# :has_one Set to `false` to disable has_one reification.
|
66
|
+
# Set to a float to change the lookback time.
|
28
67
|
def reify(options = {})
|
68
|
+
return nil if object.nil?
|
69
|
+
|
29
70
|
without_identity_map do
|
30
71
|
options[:has_one] = 3 if options[:has_one] == true
|
72
|
+
|
31
73
|
options.reverse_merge! :has_one => false
|
32
74
|
|
33
|
-
|
34
|
-
|
35
|
-
require self.item_type.underscore
|
75
|
+
#This appears to be necessary if for some reason the draft's model hasn't been loaded (such as when done in the console).
|
76
|
+
require self.item_type.underscore
|
36
77
|
|
37
|
-
|
78
|
+
loaded_object = YAML::load object
|
38
79
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
80
|
+
if item
|
81
|
+
model = item
|
82
|
+
else
|
83
|
+
inheritance_column_name = item_type.constantize.inheritance_column
|
43
84
|
|
44
|
-
|
85
|
+
class_name = loaded_object.respond_to?(inheritance_column_name.to_sym) && loaded_object.send(inheritance_column_name.to_sym).present? ? loaded_object.send(inheritance_column_name.to_sym) : item_type
|
45
86
|
|
46
|
-
|
87
|
+
klass = class_name.constantize
|
47
88
|
|
48
|
-
|
49
|
-
|
89
|
+
model = klass.new
|
90
|
+
end
|
50
91
|
|
51
|
-
|
52
|
-
|
53
|
-
|
92
|
+
has_many_associations = model.class.reflect_on_all_associations(:has_many).reject { |association| association.name == :drafts }.map { |association| association.name }
|
93
|
+
|
94
|
+
loaded_object.each do |key, value|
|
95
|
+
if model.respond_to?("#{key}=")
|
96
|
+
if has_many_associations.include?(key.to_sym)
|
97
|
+
model.send "#{key}=".to_sym, value.map { |v| model.send(key.to_sym).proxy_association.klass.new(v) }
|
54
98
|
else
|
55
|
-
|
99
|
+
model.send :write_attribute, key.to_sym, value
|
56
100
|
end
|
101
|
+
else
|
102
|
+
logger.warn "Attribute #{key} does not exist on #{item_type} (Draft ID: #{id})."
|
57
103
|
end
|
104
|
+
end
|
58
105
|
|
59
|
-
|
60
|
-
|
61
|
-
unless options[:has_one] == false
|
62
|
-
reify_has_ones model, options[:has_one]
|
63
|
-
end
|
106
|
+
model.send "#{model.class.draft_association_name}=", self
|
64
107
|
|
65
|
-
|
108
|
+
unless options[:has_one] == false
|
109
|
+
reify_has_ones model, options[:has_one]
|
66
110
|
end
|
111
|
+
|
112
|
+
model
|
67
113
|
end
|
68
114
|
end
|
69
115
|
|
70
116
|
def approve
|
117
|
+
warn 'DEPRECATED: `approve` should be handled by your application, not Kentouzu. Will be removed in Kentouzu 0.3.0.'
|
118
|
+
|
71
119
|
model = self.reify
|
72
120
|
|
73
121
|
if model
|
@@ -88,9 +136,17 @@ class Draft < ActiveRecord::Base
|
|
88
136
|
end
|
89
137
|
|
90
138
|
def reject
|
139
|
+
warn 'DEPRECATED: `reject` should be handled by your application, not Kentouzu. Will be removed in Kentouzu 0.3.0.'
|
140
|
+
|
91
141
|
self.destroy
|
92
142
|
end
|
93
143
|
|
144
|
+
def primary_key_is_int?
|
145
|
+
@primary_key_is_int ||= columns_hash[primary_key].type == :integer
|
146
|
+
rescue
|
147
|
+
true
|
148
|
+
end
|
149
|
+
|
94
150
|
private
|
95
151
|
|
96
152
|
def without_identity_map(&block)
|
data/lib/kentouzu/has_drafts.rb
CHANGED
@@ -5,41 +5,59 @@ module Kentouzu
|
|
5
5
|
end
|
6
6
|
|
7
7
|
module ClassMethods
|
8
|
+
# By calling this in your model all subsequent calls to save will instead create a draft.
|
9
|
+
# Drafts are available through the `drafts` association.
|
10
|
+
#
|
11
|
+
# Options:
|
12
|
+
# :class_name The name of a custom Draft class. Should inherit from `Kentouzu::Draft`.
|
13
|
+
# Default is `'Draft'`.
|
14
|
+
# :draft The name for the method which returns the draft the instance was reified from.
|
15
|
+
# Default is `:draft`.
|
16
|
+
# :drafts The name to use for the drafts association.
|
17
|
+
# Default is `:drafts`.
|
18
|
+
# :if Proc that allows you to specify the conditions under which drafts are made.
|
19
|
+
# :ignore An Array of attributes that will be ignored when creating a `Draft`.
|
20
|
+
# Can also accept a Has as an argument where each key is the attribute to ignore (either
|
21
|
+
# a `String` or `Symbol`) and each value is a `Proc` whose return value, `true` or
|
22
|
+
# `false`, determines if it is ignored.
|
23
|
+
# :meta A hash of extra data to store. Each key in the hash (either a `String` or `Symbol`)
|
24
|
+
# must be a column on the `drafts` table, otherwise it is ignored. You must add these
|
25
|
+
# columns yourself. The values are either objects or procs (which are called with `self`,
|
26
|
+
# i.e. the model the draft is being made from).
|
27
|
+
# :on An array of events that will cause a draft to be created.
|
28
|
+
# Defaults to `[:create, :update, :destroy]`.
|
29
|
+
# :only Inverse of the `:ignore` option. Only the attributes supplied will be passed along to
|
30
|
+
# the draft.
|
31
|
+
# :unless Proc that allows you to specify the conditions under which drafts are not made.
|
8
32
|
def has_drafts(options = {})
|
33
|
+
# Only include the instance methods when this `has_drafts` is called to avoid cluttering up models.
|
9
34
|
send :include, InstanceMethods
|
10
35
|
|
36
|
+
# Add `before_draft_save`, `after_draft_save`, and `around_draft_save` callbacks.
|
11
37
|
send :define_model_callbacks, :draft_save
|
12
38
|
|
13
39
|
class_attribute :draft_association_name
|
14
40
|
self.draft_association_name = options[:draft] || :draft
|
15
41
|
|
42
|
+
# The draft this instance was reified from.
|
16
43
|
attr_accessor self.draft_association_name
|
17
44
|
|
18
45
|
class_attribute :draft_class_name
|
19
46
|
self.draft_class_name = options[:class_name] || 'Draft'
|
20
47
|
|
21
|
-
class_attribute :
|
22
|
-
self.
|
48
|
+
class_attribute :draft_options
|
49
|
+
self.draft_options = options.dup
|
23
50
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
class_attribute :unless_condition
|
28
|
-
self.unless_condition = options[:unless]
|
29
|
-
|
30
|
-
class_attribute :skip
|
31
|
-
self.skip = ([options[:skip]].flatten.compact || []).map &:to_s
|
32
|
-
|
33
|
-
class_attribute :only
|
34
|
-
self.only = ([options[:only]].flatten.compact || []).map &:to_s
|
51
|
+
[:ignore, :only].each do |option|
|
52
|
+
draft_options[option] = [draft_options[option]].flatten.compact.map { |attr| attr.is_a?(Hash) ? attr.stringify_keys : attr.to_s }
|
53
|
+
end
|
35
54
|
|
36
|
-
|
37
|
-
self.drafts_enabled_for_model = true
|
55
|
+
draft_options[:meta] ||= {}
|
38
56
|
|
39
57
|
class_attribute :drafts_association_name
|
40
58
|
self.drafts_association_name = options[:drafts] || :drafts
|
41
59
|
|
42
|
-
if ActiveRecord::VERSION::
|
60
|
+
if ActiveRecord::VERSION::MAJOR >= 4 # `has_many` syntax for specifying order uses a lambda in Rails 4
|
43
61
|
has_many self.drafts_association_name,
|
44
62
|
lambda { order("#{Kentouzu.timestamp_field} ASC, #{self.primary_key} ASC") },
|
45
63
|
:class_name => draft_class_name,
|
@@ -49,7 +67,7 @@ module Kentouzu
|
|
49
67
|
has_many self.drafts_association_name,
|
50
68
|
:class_name => draft_class_name,
|
51
69
|
:as => :item,
|
52
|
-
:order => "#{Kentouzu.timestamp_field} ASC, #{self.
|
70
|
+
:order => "#{Kentouzu.timestamp_field} ASC, #{self.draft_class.primary_key} ASC",
|
53
71
|
:dependent => :destroy
|
54
72
|
end
|
55
73
|
|
@@ -58,7 +76,7 @@ module Kentouzu
|
|
58
76
|
end
|
59
77
|
|
60
78
|
define_singleton_method "all_with_reified_#{drafts_association_name.to_s}".to_sym do |order_by = Kentouzu.timestamp_field, &block|
|
61
|
-
existing_drafts = Draft.where("`drafts`.`item_type` = \"#{self.base_class.name}\" AND `drafts`.`item_id` IS NOT NULL").group_by { |draft| draft.item_id }.map { |
|
79
|
+
existing_drafts = Draft.where("`drafts`.`item_type` = \"#{self.base_class.name}\" AND `drafts`.`item_id` IS NOT NULL").group_by { |draft| draft.item_id }.map { |_, v| v.sort_by { |draft| draft.created_at }.last }
|
62
80
|
|
63
81
|
new_drafts = Draft.where("`drafts`.`item_type` = \"#{self.base_class.name}\" AND `drafts`.`item_id` IS NULL")
|
64
82
|
|
@@ -83,42 +101,59 @@ module Kentouzu
|
|
83
101
|
all_objects
|
84
102
|
end
|
85
103
|
|
104
|
+
def drafts_off!
|
105
|
+
Kentouzu.enabled_for_model(self, false)
|
106
|
+
end
|
107
|
+
|
86
108
|
def drafts_off
|
87
|
-
|
109
|
+
warn 'DEPRECATED: use `drafts_off!` instead of `drafts_off`. Will be removed in Kentouzu 0.3.0.'
|
110
|
+
|
111
|
+
self.drafts_off!
|
112
|
+
end
|
113
|
+
|
114
|
+
def drafts_on!
|
115
|
+
Kentouzu.enabled_for_model(self, true)
|
88
116
|
end
|
89
117
|
|
90
118
|
def drafts_on
|
91
|
-
|
119
|
+
warn 'DEPRECATED: use `drafts_on!` instead of `drafts_on`. Will be removed in Kentouzu 0.3.0.'
|
120
|
+
|
121
|
+
self.drafts_on!
|
122
|
+
end
|
123
|
+
|
124
|
+
def drafts_enabled_for_model?
|
125
|
+
Kentouzu.enabled_for_model?(self)
|
126
|
+
end
|
127
|
+
|
128
|
+
def draft_class
|
129
|
+
@draft_class ||= draft_class_name.constantize
|
92
130
|
end
|
93
131
|
end
|
94
132
|
end
|
95
133
|
|
96
134
|
module InstanceMethods
|
135
|
+
# Override the default `save` method and replace it with one that checks to see if a draft should be saved.
|
136
|
+
# If a draft should be saved the original object instance is left untouched and a new draft is created.
|
97
137
|
def self.included(base)
|
98
138
|
default_save = base.instance_method(:save)
|
99
139
|
|
100
140
|
base.send :define_method, :save do
|
101
141
|
if switched_on? && save_draft?
|
102
|
-
|
103
|
-
:item_type => self.class.base_class.to_s,
|
104
|
-
:item_id => self.id,
|
105
|
-
:event => self.persisted? ? 'update' : 'create',
|
106
|
-
:source_type => Kentouzu.source.present? ? Kentouzu.source.class.to_s : nil,
|
107
|
-
:source_id => Kentouzu.source.present? ? Kentouzu.source.id : nil,
|
108
|
-
:object => self.to_yaml
|
109
|
-
}
|
110
|
-
|
111
|
-
data.merge!(Kentouzu.controller_info.slice(:item_type, :item_id, :event, :source_type, :source_id) || {})
|
112
|
-
|
113
|
-
draft = Draft.new(data)
|
114
|
-
|
115
|
-
run_callbacks :draft_save do
|
116
|
-
draft.save
|
117
|
-
end
|
142
|
+
save_draft
|
118
143
|
else
|
119
144
|
default_save.bind(self).call
|
120
145
|
end
|
121
146
|
end
|
147
|
+
|
148
|
+
default_save_with_bang = base.instance_method(:save!)
|
149
|
+
|
150
|
+
base.send :define_method, :save! do
|
151
|
+
if switched_on? && save_draft?
|
152
|
+
save_draft
|
153
|
+
else
|
154
|
+
default_save_with_bang.bind(self).call
|
155
|
+
end
|
156
|
+
end
|
122
157
|
end
|
123
158
|
|
124
159
|
def live?
|
@@ -151,6 +186,10 @@ module Kentouzu
|
|
151
186
|
self.class.drafts_on if drafts_were_enabled
|
152
187
|
end
|
153
188
|
|
189
|
+
def drafts_enabled_for_model?
|
190
|
+
self.class.drafts_enabled_for_model?
|
191
|
+
end
|
192
|
+
|
154
193
|
private
|
155
194
|
|
156
195
|
def draft_class
|
@@ -161,12 +200,61 @@ module Kentouzu
|
|
161
200
|
send self.class.draft_association_name
|
162
201
|
end
|
163
202
|
|
203
|
+
def merge_metadata(data)
|
204
|
+
draft_options[:meta].each do |key, value|
|
205
|
+
if value.respond_to?(:call)
|
206
|
+
data[key] = value.call(self)
|
207
|
+
elsif value.is_a?(Symbol) && respond_to?(value)
|
208
|
+
data[key] = send(value)
|
209
|
+
else
|
210
|
+
data[key] = value
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
(Kentouzu.controller_info || {}).each do |key, value|
|
215
|
+
if value.respond_to?(:call)
|
216
|
+
data[key] = value.call(self)
|
217
|
+
elsif value.is_a?(Symbol) && respond_to?(value)
|
218
|
+
data[key] = send(value)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
data
|
223
|
+
end
|
224
|
+
|
225
|
+
def save_draft
|
226
|
+
data = {
|
227
|
+
:item_type => self.class.base_class.to_s,
|
228
|
+
:item_id => self.id,
|
229
|
+
:event => draft_event.to_s,
|
230
|
+
:source_type => Kentouzu.source.present? ? Kentouzu.source.class.to_s : nil,
|
231
|
+
:source_id => Kentouzu.source.present? ? Kentouzu.source.id : nil,
|
232
|
+
:object => self.as_json(include: self.class.reflect_on_all_associations(:has_many).map { |a| a.name }.reject { |a| a == :drafts }).to_yaml
|
233
|
+
}
|
234
|
+
|
235
|
+
draft = Draft.new(merge_metadata(data))
|
236
|
+
|
237
|
+
run_callbacks :draft_save do
|
238
|
+
draft.save
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def draft_event
|
243
|
+
@draft_event ||= self.persisted? ? :update : :create
|
244
|
+
end
|
245
|
+
|
164
246
|
def switched_on?
|
165
|
-
Kentouzu.enabled? && Kentouzu.enabled_for_controller? && self.
|
247
|
+
Kentouzu.enabled? && Kentouzu.enabled_for_controller? && self.drafts_enabled_for_model?
|
166
248
|
end
|
167
249
|
|
168
250
|
def save_draft?
|
169
|
-
|
251
|
+
on_events = Array(self.draft_options[:on])
|
252
|
+
|
253
|
+
if_condition = self.draft_options[:if]
|
254
|
+
|
255
|
+
unless_condition = self.draft_options[:unless]
|
256
|
+
|
257
|
+
(on_events.empty? || on_events.include?(draft_event)) && (if_condition.blank? || if_condition.call(self)) && !unless_condition.try(:call, self)
|
170
258
|
end
|
171
259
|
end
|
172
260
|
end
|
data/lib/kentouzu/version.rb
CHANGED
data/lib/kentouzu.rb
CHANGED
@@ -4,64 +4,110 @@ require 'yaml'
|
|
4
4
|
require 'kentouzu/config'
|
5
5
|
require 'kentouzu/controller'
|
6
6
|
require 'kentouzu/has_drafts'
|
7
|
-
require 'kentouzu/draft'
|
8
7
|
|
9
8
|
module Kentouzu
|
9
|
+
# Switches Kentouzu on or off globally.
|
10
10
|
def self.enabled=(value)
|
11
11
|
Kentouzu.config.enabled = value
|
12
12
|
end
|
13
13
|
|
14
|
+
# Returns `true` if Kentouzu is enabled globally, `false` otherwise.
|
15
|
+
# Kentouzu is enabled by default.
|
14
16
|
def self.enabled?
|
15
17
|
!!Kentouzu.config.enabled
|
16
18
|
end
|
17
19
|
|
20
|
+
# Switches Kentouzu on or off for the current request.
|
18
21
|
def self.enabled_for_controller=(value)
|
19
22
|
drafts_store[:request_enabled_for_controller] = value
|
20
23
|
end
|
21
24
|
|
25
|
+
# Returns `true` if Kentouzu is enabled for the current request, `false` otherwise.
|
22
26
|
def self.enabled_for_controller?
|
23
27
|
!!drafts_store[:request_enabled_for_controller]
|
24
28
|
end
|
25
29
|
|
30
|
+
# Switches Kentouzu on or off for the model for the current request.
|
31
|
+
def self.enabled_for_model(model, value)
|
32
|
+
drafts_store[:"enabled_for_#{model}"] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns `true` if Kentouzu is enabled for the model for the current request, `false` otherwise.
|
36
|
+
def self.enabled_for_model?(model)
|
37
|
+
!!drafts_store.fetch(:"enabled_for_#{model}", true)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Set the field which records when a draft was created.
|
26
41
|
def self.timestamp_field=(field_name)
|
27
42
|
Kentouzu.config.timestamp_field = field_name
|
28
43
|
end
|
29
44
|
|
45
|
+
# Returns the field which records when a draft was created.
|
30
46
|
def self.timestamp_field
|
31
47
|
Kentouzu.config.timestamp_field
|
32
48
|
end
|
33
49
|
|
50
|
+
# Sets who is responsible for creating the draft.
|
51
|
+
# Inside of a controller this will automatically be set to `current_user`.
|
52
|
+
# Outside of a controller it will need to be set manually.
|
34
53
|
def self.source=(value)
|
35
54
|
drafts_store[:source] = value
|
36
55
|
end
|
37
56
|
|
57
|
+
# Returns who is responsible for creating the draft.
|
38
58
|
def self.source
|
39
59
|
drafts_store[:source]
|
40
60
|
end
|
41
61
|
|
62
|
+
# Sets any information from the controller that you want Kentouzu to store.
|
42
63
|
def self.controller_info=(value)
|
43
64
|
drafts_store[:controller_info] = value
|
44
65
|
end
|
45
66
|
|
67
|
+
# Returns any information from the controller that you want Kentouzu to store.
|
46
68
|
def self.controller_info
|
47
69
|
drafts_store[:controller_info]
|
48
70
|
end
|
49
71
|
|
72
|
+
# Returns `true` if ActiveRecord requires mass assigned attributes to be whitelisted via `attr_accessible`, `false` otherwise.
|
73
|
+
def self.active_record_protected_attributes?
|
74
|
+
@active_record_protected_attributes ||= ActiveRecord::VERSION::MAJOR < 4 || !!defined?(ProtectedAttributes)
|
75
|
+
end
|
76
|
+
|
50
77
|
private
|
51
78
|
|
79
|
+
# Thread-safe hash to hold Kentouzu's data.
|
80
|
+
# Initialized to enable Kentouzu for all controllers.
|
52
81
|
def self.drafts_store
|
53
82
|
Thread.current[:draft] ||= { :request_enabled_for_controller => true }
|
54
83
|
end
|
55
84
|
|
85
|
+
# Returns Kentouzu's configuration object.
|
56
86
|
def self.config
|
57
87
|
@@config ||= Kentouzu::Config.instance
|
58
88
|
end
|
59
89
|
end
|
60
90
|
|
91
|
+
require 'kentouzu/draft'
|
92
|
+
|
93
|
+
# Ensure `protected_attributes` gem gets required if it is available before the `Draft` class is loaded.
|
94
|
+
unless Kentouzu.active_record_protected_attributes?
|
95
|
+
Kentouzu.send(:remove_instance_variable, :@active_record_protected_attributes)
|
96
|
+
|
97
|
+
begin
|
98
|
+
require 'protected_attributes'
|
99
|
+
rescue LoadError
|
100
|
+
# Don't blow up if the `protected_attributes` gem is not available.
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Include `Kentouzu::Model` into `ActiveRecord::Base`
|
61
106
|
ActiveSupport.on_load(:active_record) do
|
62
107
|
include Kentouzu::Model
|
63
108
|
end
|
64
109
|
|
110
|
+
# Include `Kentouzu::Controller` into `ActionController::Base`
|
65
111
|
ActiveSupport.on_load(:action_controller) do
|
66
112
|
include Kentouzu::Controller
|
67
113
|
end
|
metadata
CHANGED
@@ -1,187 +1,165 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kentouzu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Sean Eshbaugh
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-21 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: railties
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '3.0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '3.0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activerecord
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '3.0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '3.0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: capybara
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: database_cleaner
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - ">="
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: jquery-rails
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - ">="
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - ">="
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rake
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - ">="
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - ">="
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: rails
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - ">="
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '3.2'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - ">="
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '3.2'
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: rspec-rails
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
|
-
- -
|
115
|
+
- - ">="
|
132
116
|
- !ruby/object:Gem::Version
|
133
117
|
version: '0'
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
|
-
- -
|
122
|
+
- - ">="
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: '0'
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: shoulda-matchers
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
|
-
- -
|
129
|
+
- - ">="
|
148
130
|
- !ruby/object:Gem::Version
|
149
131
|
version: '0'
|
150
132
|
type: :development
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
|
-
- -
|
136
|
+
- - ">="
|
156
137
|
- !ruby/object:Gem::Version
|
157
138
|
version: '0'
|
158
139
|
- !ruby/object:Gem::Dependency
|
159
140
|
name: sqlite3
|
160
141
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
142
|
requirements:
|
163
|
-
- -
|
143
|
+
- - ">="
|
164
144
|
- !ruby/object:Gem::Version
|
165
145
|
version: '0'
|
166
146
|
type: :development
|
167
147
|
prerelease: false
|
168
148
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
149
|
requirements:
|
171
|
-
- -
|
150
|
+
- - ">="
|
172
151
|
- !ruby/object:Gem::Version
|
173
152
|
version: '0'
|
174
153
|
description: Add drafts to ActiveRecord models.
|
175
|
-
email:
|
176
|
-
- seaneshbaugh@gmail.com
|
154
|
+
email: seaneshbaugh@gmail.com
|
177
155
|
executables: []
|
178
156
|
extensions: []
|
179
157
|
extra_rdoc_files: []
|
180
158
|
files:
|
181
|
-
- .gitignore
|
182
|
-
- .rspec
|
183
|
-
- .ruby-gemset
|
184
|
-
- .ruby-version
|
159
|
+
- ".gitignore"
|
160
|
+
- ".rspec"
|
161
|
+
- ".ruby-gemset"
|
162
|
+
- ".ruby-version"
|
185
163
|
- CHANGELOG.md
|
186
164
|
- Gemfile
|
187
165
|
- Gemfile.lock
|
@@ -247,33 +225,26 @@ files:
|
|
247
225
|
- spec/spec_helper.rb
|
248
226
|
homepage: https://github.com/seaneshbaugh/kentouzu
|
249
227
|
licenses: []
|
228
|
+
metadata: {}
|
250
229
|
post_install_message:
|
251
230
|
rdoc_options: []
|
252
231
|
require_paths:
|
253
232
|
- lib
|
254
233
|
required_ruby_version: !ruby/object:Gem::Requirement
|
255
|
-
none: false
|
256
234
|
requirements:
|
257
|
-
- -
|
235
|
+
- - ">="
|
258
236
|
- !ruby/object:Gem::Version
|
259
237
|
version: '0'
|
260
|
-
segments:
|
261
|
-
- 0
|
262
|
-
hash: -3194602278824882459
|
263
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
264
|
-
none: false
|
265
239
|
requirements:
|
266
|
-
- -
|
240
|
+
- - ">="
|
267
241
|
- !ruby/object:Gem::Version
|
268
242
|
version: '0'
|
269
|
-
segments:
|
270
|
-
- 0
|
271
|
-
hash: -3194602278824882459
|
272
243
|
requirements: []
|
273
|
-
rubyforge_project:
|
274
|
-
rubygems_version:
|
244
|
+
rubyforge_project:
|
245
|
+
rubygems_version: 2.2.2
|
275
246
|
signing_key:
|
276
|
-
specification_version:
|
247
|
+
specification_version: 4
|
277
248
|
summary: Add drafts to ActiveRecord models.
|
278
249
|
test_files:
|
279
250
|
- spec/dummy/Rakefile
|