purgatory 2.14.0 → 3.0.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 +8 -8
- data/README.markdown +18 -1
- data/VERSION +1 -1
- data/lib/generators/purgatory/purgatory_generator.rb +5 -1
- data/lib/generators/purgatory/templates/add_performable_method_to_purgatories.rb +5 -0
- data/lib/purgatory/purgatory.rb +4 -2
- data/lib/purgatory/purgatory_module.rb +17 -0
- data/purgatory.gemspec +6 -5
- data/spec/purgatory_spec.rb +68 -0
- data/spec/support/active_record.rb +2 -0
- data/spec/support/widget.rb +4 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NmFlNGZiY2ZlNWNkYzRkNzc2MDJlOWIxM2RiZjMyYTNhNjRmMDc5NA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZWRmYWJjYzg2Mzg2ZjFmZjE1MmVjYjM5ZDU5Y2I0MTE0MDRhYmE4Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MzI4OTMzYWQ2NTBhNWMyM2ExNTc3NTE2OWJiMmE2MTE2Mzc4MDhkYWJmZDQw
|
10
|
+
MTgyMDdhYWQ0MTg5MGJiMWM2NWZjNmIxMmE1MzZhODgzN2QxNjhiNDI5ODRj
|
11
|
+
YjRmOWZjMGZjNWQ1YmZlYjM4OWQ0YzExMTFhNDlmNTljMTUxOTM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmZmNDRjY2MwYWEzNjA2MTdlZTRjY2U1ZGJlZmFjYTk2ZDRlOTcxYjNiYmRi
|
14
|
+
MDkxMGIzNzQzNGEwOTAzZWFhMmJlOGRjOWIwMDU1YmNhYzZmZjA5NTliMGUy
|
15
|
+
MzFkYzQ1ZWExZjQzMjg2NTRjYjE1ZDhkZTQzYzU5NzkxMGIyYjU=
|
data/README.markdown
CHANGED
@@ -41,6 +41,14 @@ You can also put the creation of a new object into Purgatory
|
|
41
41
|
item = Item.new price: 100
|
42
42
|
purgatory = item.purgatory!
|
43
43
|
|
44
|
+
Call .purgatize.method(params) to put a method call into Purgatory. When the purgatory is approved the method will be called on the soul
|
45
|
+
|
46
|
+
#without purgatory:
|
47
|
+
item.increase_price(200)
|
48
|
+
|
49
|
+
#with purgatory:
|
50
|
+
item.purgatize(current_user).increase_price(200)
|
51
|
+
|
44
52
|
The following are some attributes of a purgatory:
|
45
53
|
|
46
54
|
purgatory.soul # The ActiveRecord model instance whose changes are in purgatory
|
@@ -49,6 +57,7 @@ The following are some attributes of a purgatory:
|
|
49
57
|
purgatory.requested_changes # A hash of the proposed changes. The keys are the attribute names and the values are 2-element arrays where the 1st element is the old value and the 2nd element is the new value
|
50
58
|
purgatory.approver # The user who approved the purgatory
|
51
59
|
purgatory.approved_at # The time when the purgatory was approved
|
60
|
+
purgatory.performable_method # Information about the method to call on the soul when the purgatory is approved
|
52
61
|
|
53
62
|
Here are some handy class and instance methods available to you:
|
54
63
|
|
@@ -110,7 +119,15 @@ Here are some handy class and instance methods available to you:
|
|
110
119
|
use_purgatory :local_attributes => :all
|
111
120
|
|
112
121
|
By specifying all, Purgatory will programmatically determine what the virtual attributes are and save them when "purgatory!" is called, so that they will be available during "approve!".
|
113
|
-
|
122
|
+
|
123
|
+
## Updating Purgatory Version
|
124
|
+
|
125
|
+
Whenever you update the version of purgatory you will need to:
|
126
|
+
|
127
|
+
1. Run the generator to create required migrations
|
128
|
+
$ rails generate purgatory
|
129
|
+
2. Migrate the database
|
130
|
+
$ rake db:migrate
|
114
131
|
|
115
132
|
## Contributing to Purgatory
|
116
133
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
@@ -17,7 +17,11 @@ class PurgatoryGenerator < Rails::Generators::Base
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def create_migration_file
|
20
|
-
|
20
|
+
['create_purgatories', 'add_performable_method_to_purgatories'].each do |filename|
|
21
|
+
unless self.class.migration_exists?("db/migrate", "#{filename}").present?
|
22
|
+
migration_template "#{filename}.rb", "db/migrate/#{filename}.rb"
|
23
|
+
end
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
27
|
def create_initializer_file
|
data/lib/purgatory/purgatory.rb
CHANGED
@@ -11,6 +11,7 @@ class Purgatory < ActiveRecord::Base
|
|
11
11
|
|
12
12
|
serialize :requested_changes
|
13
13
|
serialize :attr_accessor_fields
|
14
|
+
serialize :performable_method
|
14
15
|
|
15
16
|
def self.pending
|
16
17
|
where(approved_at: nil)
|
@@ -37,14 +38,15 @@ class Purgatory < ActiveRecord::Base
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def soul_with_changes
|
40
|
-
requested_changes.each{|k,v| soul.send(:write_attribute, k, v[1])}
|
41
|
-
attr_accessor_fields.each{|k,v| soul.instance_variable_set(k, v)}
|
41
|
+
requested_changes.each{|k,v| soul.send(:write_attribute, k, v[1])} if requested_changes
|
42
|
+
attr_accessor_fields.each{|k,v| soul.instance_variable_set(k, v)} if attr_accessor_fields
|
42
43
|
soul
|
43
44
|
end
|
44
45
|
|
45
46
|
def approve!(approver = nil)
|
46
47
|
return false if approved?
|
47
48
|
if soul_with_changes.save
|
49
|
+
soul.send(performable_method[:method],*performable_method[:args]) if performable_method
|
48
50
|
self.approver = approver
|
49
51
|
self.approved_at = Time.now
|
50
52
|
self.soul_id = soul.id
|
@@ -10,6 +10,10 @@ module PurgatoryModule
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def purgatize(requester = nil, options = {})
|
14
|
+
Purgatization.new(self, requester, options)
|
15
|
+
end
|
16
|
+
|
13
17
|
def purgatory!(requester = nil, options = {})
|
14
18
|
return nil if self.invalid?
|
15
19
|
return nil if Purgatory.pending_with_matching_soul(self).any? && options[:fail_if_matching_soul]
|
@@ -20,6 +24,19 @@ module PurgatoryModule
|
|
20
24
|
attr_accessor :user_class_name
|
21
25
|
end
|
22
26
|
|
27
|
+
class Purgatization
|
28
|
+
def initialize(soul, requester, options)
|
29
|
+
@soul = soul
|
30
|
+
@requester = requester
|
31
|
+
@options = options
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(method, *args)
|
35
|
+
return nil if Purgatory.pending_with_matching_soul(@soul).any? && @options[:fail_if_matching_soul]
|
36
|
+
Purgatory.create soul: @soul, requester: @requester, performable_method: {method: method.to_sym, args: args}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
23
40
|
class << self
|
24
41
|
def configure(&block)
|
25
42
|
yield(configuration)
|
data/purgatory.gemspec
CHANGED
@@ -2,15 +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: purgatory
|
5
|
+
# stub: purgatory 3.0.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "purgatory"
|
9
|
-
s.version = "
|
9
|
+
s.version = "3.0.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
12
13
|
s.authors = ["Elan Dubrofsky"]
|
13
|
-
s.date = "
|
14
|
+
s.date = "2014-11-07"
|
14
15
|
s.description = "Put your model changes in purgatory and allow them to remain lost souls until they are approved"
|
15
16
|
s.email = "elan.dubrofsky@gmail.com"
|
16
17
|
s.extra_rdoc_files = [
|
@@ -29,6 +30,7 @@ Gem::Specification.new do |s|
|
|
29
30
|
"VERSION",
|
30
31
|
"init.rb",
|
31
32
|
"lib/generators/purgatory/purgatory_generator.rb",
|
33
|
+
"lib/generators/purgatory/templates/add_performable_method_to_purgatories.rb",
|
32
34
|
"lib/generators/purgatory/templates/create_purgatories.rb",
|
33
35
|
"lib/purgatory.rb",
|
34
36
|
"lib/purgatory/active_record_descendant_attribute_accessors.rb",
|
@@ -45,8 +47,7 @@ Gem::Specification.new do |s|
|
|
45
47
|
]
|
46
48
|
s.homepage = "http://github.com/financeit/purgatory"
|
47
49
|
s.licenses = ["MIT"]
|
48
|
-
s.
|
49
|
-
s.rubygems_version = "2.1.11"
|
50
|
+
s.rubygems_version = "2.2.2"
|
50
51
|
s.summary = "Allow changes to a model to be put in purgatory until they are approved"
|
51
52
|
|
52
53
|
if s.respond_to? :specification_version then
|
data/spec/purgatory_spec.rb
CHANGED
@@ -346,6 +346,16 @@ describe Purgatory do
|
|
346
346
|
@purgatory.approve!(user2).should be_false
|
347
347
|
end
|
348
348
|
end
|
349
|
+
|
350
|
+
context "approving method call purgatory" do
|
351
|
+
before{create_method_call_purgatory}
|
352
|
+
it "should call the method" do
|
353
|
+
@widget.name.should == 'foo'
|
354
|
+
@purgatory.approve!
|
355
|
+
@widget.reload
|
356
|
+
@widget.name.should == 'bar'
|
357
|
+
end
|
358
|
+
end
|
349
359
|
end
|
350
360
|
|
351
361
|
describe "use_purgatory" do
|
@@ -552,6 +562,57 @@ describe Purgatory do
|
|
552
562
|
end
|
553
563
|
end
|
554
564
|
end
|
565
|
+
context :purgatize do
|
566
|
+
context "putting method call into purgatory" do
|
567
|
+
context "valid changes" do
|
568
|
+
before {create_method_call_purgatory}
|
569
|
+
|
570
|
+
it "should create and return pending Purgatory object" do
|
571
|
+
@purgatory.should be_present
|
572
|
+
@purgatory.should_not be_approved
|
573
|
+
@purgatory.should be_pending
|
574
|
+
Purgatory.pending.count.should == 1
|
575
|
+
Purgatory.pending.first.should == @purgatory
|
576
|
+
Purgatory.approved.count.should be_zero
|
577
|
+
end
|
578
|
+
|
579
|
+
it "should store the soul, requester and performable_method" do
|
580
|
+
@purgatory.soul.should == @widget
|
581
|
+
@purgatory.requester.should == user1
|
582
|
+
@purgatory.performable_method[:method].should == :rename
|
583
|
+
@purgatory.performable_method[:args].should == ['bar']
|
584
|
+
end
|
585
|
+
|
586
|
+
it "should delete old pending purgatories with same soul" do
|
587
|
+
@widget2 = Widget.create name: 'toy', price: 500
|
588
|
+
@widget2.name = 'Big Toy'
|
589
|
+
widget2_purgatory = @widget2.purgatize(user1).rename('bar')
|
590
|
+
@widget.name = 'baz'
|
591
|
+
new_purgatory = @widget.purgatize(user1).rename('bar')
|
592
|
+
Purgatory.find_by_id(@purgatory.id).should be_nil
|
593
|
+
Purgatory.find_by_id(widget2_purgatory.id).should be_present
|
594
|
+
Purgatory.pending.count.should == 2
|
595
|
+
Purgatory.last.requested_changes['name'].should == ['foo', 'baz']
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should fail to create purgatory if matching pending Purgatory exists and fail_if_matching_soul is passed in" do
|
599
|
+
@widget.name = 'baz'
|
600
|
+
new_purgatory = @widget.purgatize(user1, fail_if_matching_soul: true).rename('bar')
|
601
|
+
new_purgatory.should be_nil
|
602
|
+
Purgatory.find_by_id(@purgatory.id).should be_present
|
603
|
+
Purgatory.pending.count.should == 1
|
604
|
+
end
|
605
|
+
|
606
|
+
it "should succeed to create purgatory if matching approved Purgatory exists and fail_if_matching_soul is passed in" do
|
607
|
+
@purgatory.approve!
|
608
|
+
@widget.name = 'baz'
|
609
|
+
new_purgatory = @widget.purgatize(user1, fail_if_matching_soul: true).rename('bar')
|
610
|
+
new_purgatory.should be_present
|
611
|
+
Purgatory.count.should == 2
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
end
|
555
616
|
end
|
556
617
|
|
557
618
|
private
|
@@ -565,6 +626,13 @@ describe Purgatory do
|
|
565
626
|
@widget.reload
|
566
627
|
end
|
567
628
|
|
629
|
+
def create_method_call_purgatory
|
630
|
+
@widget = Widget.create name: 'foo', price: 100
|
631
|
+
purgatory = @widget.purgatize(user1).rename('bar')
|
632
|
+
@purgatory = Purgatory.find(purgatory.id)
|
633
|
+
@widget.reload
|
634
|
+
end
|
635
|
+
|
568
636
|
def create_new_object_purgatory
|
569
637
|
widget = Widget.new name: 'foo', price: 100
|
570
638
|
purgatory = widget.purgatory! user1
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
require 'generators/purgatory/templates/create_purgatories'
|
3
|
+
require 'generators/purgatory/templates/add_performable_method_to_purgatories'
|
3
4
|
require 'purgatory/purgatory_module'
|
4
5
|
|
5
6
|
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
@@ -31,6 +32,7 @@ ActiveRecord::Migration.create_table :items do |t|
|
|
31
32
|
end
|
32
33
|
|
33
34
|
CreatePurgatories.new.migrate(:up)
|
35
|
+
AddPerformableMethodToPurgatories.new.migrate(:up)
|
34
36
|
|
35
37
|
PurgatoryModule.configure do |config|
|
36
38
|
config.user_class_name = 'User'
|
data/spec/support/widget.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: purgatory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elan Dubrofsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- VERSION
|
73
73
|
- init.rb
|
74
74
|
- lib/generators/purgatory/purgatory_generator.rb
|
75
|
+
- lib/generators/purgatory/templates/add_performable_method_to_purgatories.rb
|
75
76
|
- lib/generators/purgatory/templates/create_purgatories.rb
|
76
77
|
- lib/purgatory.rb
|
77
78
|
- lib/purgatory/active_record_descendant_attribute_accessors.rb
|
@@ -105,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
106
|
version: '0'
|
106
107
|
requirements: []
|
107
108
|
rubyforge_project:
|
108
|
-
rubygems_version: 2.
|
109
|
+
rubygems_version: 2.2.2
|
109
110
|
signing_key:
|
110
111
|
specification_version: 4
|
111
112
|
summary: Allow changes to a model to be put in purgatory until they are approved
|