approval 0.2.3 → 0.3.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/README.md +17 -11
- data/lib/approval/config.rb +0 -2
- data/lib/approval/mixins.rb +1 -1
- data/lib/approval/mixins/resource.rb +9 -5
- data/lib/approval/mixins/user.rb +3 -0
- data/lib/approval/models/approval/comment.rb +6 -1
- data/lib/approval/models/approval/item.rb +1 -0
- data/lib/approval/models/approval/request.rb +7 -4
- data/lib/approval/models/approval/request_form/create.rb +2 -2
- data/lib/approval/models/approval/request_form/destroy.rb +1 -1
- data/lib/approval/models/approval/request_form/update.rb +2 -2
- data/lib/approval/models/approval/respond_form/approve.rb +1 -1
- data/lib/approval/models/approval/respond_form/cancel.rb +1 -1
- data/lib/approval/models/approval/respond_form/reject.rb +1 -1
- data/lib/approval/version.rb +1 -1
- data/lib/generators/approval/templates/initializer.rb +0 -3
- data/spec/models/book_spec.rb +15 -12
- data/spec/models/comment_spec.rb +1 -1
- data/spec/models/request_form/update_spec.rb +12 -2
- data/spec/models/request_spec.rb +2 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f6a5f60b035099e2da46cd42dc3c09deafe3b8a
|
4
|
+
data.tar.gz: 920839f43297af114060d06f66f2256a22b2040b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf0ef7bdf54a232f8e2e0bf200c952b5e5dedbfebc8d9606c405b135863387c2eb4b3732f1d93bf132d922a4371a9fa4a0da2edb77b43f3569524dced809faea
|
7
|
+
data.tar.gz: bdd3df5ceff8e92e949df3baa53860b1a374962a0564879520f4be02c07687fa1010fa6cb1b7bbd941c950706417efcadc25183fcbd184769f01724256b7e238
|
data/README.md
CHANGED
@@ -30,7 +30,7 @@
|
|
30
30
|
4. Add `acts_as_approval_resource` to the models you want use approval flow:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
class
|
33
|
+
class Book < ApplicationRecord
|
34
34
|
acts_as_approval_resource
|
35
35
|
end
|
36
36
|
```
|
@@ -44,7 +44,7 @@ You send request, but resources aren't created/updated/destroied.
|
|
44
44
|
#### :pray: Create
|
45
45
|
|
46
46
|
```ruby
|
47
|
-
staff
|
47
|
+
staff = User.find_or_create_by(email: "staff@example.com")
|
48
48
|
|
49
49
|
record = Book.new(name: "Ruby Way", price: 2980)
|
50
50
|
request = staff.request_for_create(record, reason: "something")
|
@@ -58,13 +58,13 @@ request.save!
|
|
58
58
|
#### :pray: Update
|
59
59
|
|
60
60
|
```ruby
|
61
|
-
staff
|
61
|
+
staff = User.find_or_create_by(email: "staff@example.com")
|
62
62
|
|
63
63
|
record = Book.find(1).tap {|record| record.name = "new book title" }
|
64
64
|
request = staff.request_for_update(record, reason: "something")
|
65
65
|
request.save
|
66
66
|
|
67
|
-
records = Book.where(id: 1, 2, 3).
|
67
|
+
records = Book.where(id: [1, 2, 3]).each {|record| record.price *= 0.5 }
|
68
68
|
request = staff.request_for_update(records, reason: "something")
|
69
69
|
request.save!
|
70
70
|
```
|
@@ -72,13 +72,13 @@ request.save!
|
|
72
72
|
#### :pray: Destroy
|
73
73
|
|
74
74
|
```ruby
|
75
|
-
staff
|
75
|
+
staff = User.find_or_create_by(email: "staff@example.com")
|
76
76
|
|
77
77
|
record = Book.find(1)
|
78
78
|
request = staff.request_for_destroy(record, reason: "something")
|
79
79
|
request.save
|
80
80
|
|
81
|
-
records = Book.where(id: 1, 2, 3)
|
81
|
+
records = Book.where(id: [1, 2, 3])
|
82
82
|
request = staff.request_for_destroy(records, reason: "something")
|
83
83
|
request.save!
|
84
84
|
```
|
@@ -90,7 +90,7 @@ request.save!
|
|
90
90
|
Then resources are created/updated/destroied, if respond user have approved the request.
|
91
91
|
|
92
92
|
```ruby
|
93
|
-
admin
|
93
|
+
admin = User.find_or_create_by(email: "admin@example.com")
|
94
94
|
|
95
95
|
request = Approval::Request.first
|
96
96
|
respond = admin.approve_request(request, reason: "something")
|
@@ -102,7 +102,7 @@ respond.save! # Create/Update/Destroy resources
|
|
102
102
|
Then resources are not created/updated/destroied, if respond user have rejected the request.
|
103
103
|
|
104
104
|
```ruby
|
105
|
-
admin
|
105
|
+
admin = User.find_or_create_by(email: "admin@example.com")
|
106
106
|
|
107
107
|
request = Approval::Request.first
|
108
108
|
respond = admin.reject_request(request, reason: "something")
|
@@ -119,15 +119,21 @@ respond = staff.cancel_request(request, reason: "something")
|
|
119
119
|
respond.save!
|
120
120
|
```
|
121
121
|
|
122
|
+
### Comment
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
admin = User.find_or_create_by(email: "admin@example.com")
|
126
|
+
|
127
|
+
request = Approval::Request.first
|
128
|
+
admin.approval_comments.create(request: request, content: "Hello")
|
129
|
+
```
|
130
|
+
|
122
131
|
### Configuration
|
123
132
|
|
124
133
|
```ruby
|
125
134
|
# config/initializers/approval.rb
|
126
135
|
|
127
136
|
Approval.configure do |config|
|
128
|
-
# Your user model name (e.g. User, AdminUser, Member, default: User)
|
129
|
-
config.user_class_name = "User"
|
130
|
-
|
131
137
|
# Maximum characters of comment for reason (default: 2000)
|
132
138
|
config.comment_maximum = 2000
|
133
139
|
|
data/lib/approval/config.rb
CHANGED
@@ -2,13 +2,11 @@ module Approval
|
|
2
2
|
class Config
|
3
3
|
attr_accessor(
|
4
4
|
:comment_maximum,
|
5
|
-
:user_class_name,
|
6
5
|
:permit_to_respond_to_own_request,
|
7
6
|
)
|
8
7
|
|
9
8
|
def initialize
|
10
9
|
@comment_maximum = 2000
|
11
|
-
@user_class_name = "User"
|
12
10
|
@permit_to_respond_to_own_request = false
|
13
11
|
end
|
14
12
|
|
data/lib/approval/mixins.rb
CHANGED
@@ -3,22 +3,26 @@ module Approval
|
|
3
3
|
module Resource
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
DEFAULT_IGNORE_FIELDS = %w[id created_at updated_at].freeze
|
7
|
-
|
8
6
|
included do
|
9
7
|
class_attribute :approval_ignore_fields
|
8
|
+
self.approval_ignore_fields = %w[id created_at updated_at]
|
9
|
+
|
10
10
|
has_many :approval_items, class_name: :"Approval::Item", as: :resource
|
11
11
|
end
|
12
12
|
|
13
13
|
class_methods do
|
14
|
-
def
|
15
|
-
self.approval_ignore_fields =
|
14
|
+
def assign_ignore_fields(ignore_fields = [])
|
15
|
+
self.approval_ignore_fields = approval_ignore_fields.concat(ignore_fields).map(&:to_s).uniq
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def create_params_for_approval
|
20
20
|
attributes.except(*approval_ignore_fields).compact
|
21
21
|
end
|
22
|
+
|
23
|
+
def update_params_for_approval
|
24
|
+
changes.except(*approval_ignore_fields).each_with_object({}) { |(k, v), h| h[k] = v.last }.compact
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
data/lib/approval/mixins/user.rb
CHANGED
@@ -6,6 +6,9 @@ module Approval
|
|
6
6
|
included do
|
7
7
|
has_many :approval_requests, class_name: :"Approval::Request", foreign_key: :request_user_id
|
8
8
|
has_many :approval_comments, class_name: :"Approval::Comment", foreign_key: :user_id
|
9
|
+
|
10
|
+
Approval::Request.define_user_association(self)
|
11
|
+
Approval::Comment.define_user_association(self)
|
9
12
|
end
|
10
13
|
|
11
14
|
def request_for_create(records, reason:)
|
@@ -2,8 +2,13 @@ module Approval
|
|
2
2
|
class Comment < ::ActiveRecord::Base
|
3
3
|
self.table_name_prefix = "approval_".freeze
|
4
4
|
|
5
|
+
class << self
|
6
|
+
def define_user_association(klass)
|
7
|
+
belongs_to :user, class_name: klass.to_s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
belongs_to :request, class_name: :"Approval::Request", inverse_of: :comments
|
6
|
-
belongs_to :user, class_name: Approval.config.user_class_name
|
7
12
|
|
8
13
|
validates :content, presence: true, length: { maximum: Approval.config.comment_maximum }
|
9
14
|
end
|
@@ -2,9 +2,13 @@ module Approval
|
|
2
2
|
class Request < ::ActiveRecord::Base
|
3
3
|
self.table_name_prefix = "approval_".freeze
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class << self
|
6
|
+
def define_user_association(klass)
|
7
|
+
with_options class_name: klass.to_s do
|
8
|
+
belongs_to :request_user
|
9
|
+
belongs_to :respond_user, optional: true
|
10
|
+
end
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
with_options dependent: :destroy, inverse_of: :request do
|
@@ -18,7 +22,6 @@ module Approval
|
|
18
22
|
|
19
23
|
with_options presence: true do
|
20
24
|
validates :state
|
21
|
-
validates :request_user
|
22
25
|
validates :respond_user, unless: :pending?
|
23
26
|
validates :comments
|
24
27
|
validates :items
|
@@ -4,14 +4,14 @@ module Approval
|
|
4
4
|
private
|
5
5
|
|
6
6
|
def prepare
|
7
|
-
::
|
7
|
+
::Approval::Request.transaction do
|
8
8
|
request = user.approval_requests.new
|
9
9
|
request.comments.new(user: user, content: reason)
|
10
10
|
Array(records).each do |record|
|
11
11
|
request.items.new(
|
12
12
|
event: "create",
|
13
13
|
resource_type: record.class.to_s,
|
14
|
-
params: record.
|
14
|
+
params: record.create_params_for_approval,
|
15
15
|
)
|
16
16
|
end
|
17
17
|
yield(request)
|
@@ -4,7 +4,7 @@ module Approval
|
|
4
4
|
private
|
5
5
|
|
6
6
|
def prepare
|
7
|
-
::
|
7
|
+
::Approval::Request.transaction do
|
8
8
|
request = user.approval_requests.new
|
9
9
|
request.comments.new(user: user, content: reason)
|
10
10
|
Array(records).each do |record|
|
@@ -12,7 +12,7 @@ module Approval
|
|
12
12
|
event: "update",
|
13
13
|
resource_type: record.class.to_s,
|
14
14
|
resource_id: record.id,
|
15
|
-
params: record.
|
15
|
+
params: record.update_params_for_approval,
|
16
16
|
)
|
17
17
|
end
|
18
18
|
yield(request)
|
@@ -6,7 +6,7 @@ module Approval
|
|
6
6
|
private
|
7
7
|
|
8
8
|
def prepare
|
9
|
-
::
|
9
|
+
::Approval::Request.transaction do
|
10
10
|
request.lock!
|
11
11
|
request.assign_attributes(state: :approved, approved_at: Time.current, respond_user: user)
|
12
12
|
request.comments.new(user: user, content: reason)
|
@@ -4,7 +4,7 @@ module Approval
|
|
4
4
|
private
|
5
5
|
|
6
6
|
def prepare
|
7
|
-
::
|
7
|
+
::Approval::Request.transaction do
|
8
8
|
request.lock!
|
9
9
|
request.assign_attributes(state: :cancelled, cancelled_at: Time.current, respond_user: user)
|
10
10
|
request.comments.new(user: user, content: reason)
|
@@ -6,7 +6,7 @@ module Approval
|
|
6
6
|
private
|
7
7
|
|
8
8
|
def prepare
|
9
|
-
::
|
9
|
+
::Approval::Request.transaction do
|
10
10
|
request.lock!
|
11
11
|
request.assign_attributes(state: :rejected, rejected_at: Time.current, respond_user: user)
|
12
12
|
request.comments.new(user: user, content: reason)
|
data/lib/approval/version.rb
CHANGED
data/spec/models/book_spec.rb
CHANGED
@@ -3,25 +3,28 @@ require "spec_helper"
|
|
3
3
|
RSpec.describe Book, type: :model do
|
4
4
|
it { is_expected.to have_many(:approval_items).class_name("Approval::Item") }
|
5
5
|
|
6
|
-
describe ".
|
7
|
-
subject { described_class.
|
6
|
+
describe ".assign_ignore_fields" do
|
7
|
+
subject { described_class.assign_ignore_fields(ignore_fields) }
|
8
8
|
|
9
|
-
context "when ignore_fields are
|
10
|
-
let(:ignore_fields) { [] }
|
11
|
-
it { is_expected.to match_array
|
12
|
-
end
|
13
|
-
|
14
|
-
context "when ignore_fields are present" do
|
15
|
-
let(:ignore_fields) { ["published_at"] }
|
16
|
-
it { is_expected.to match_array Approval::Mixins::Resource::DEFAULT_IGNORE_FIELDS.dup.concat(["published_at"]) }
|
9
|
+
context "when ignore_fields are duplicated symbolized value" do
|
10
|
+
let(:ignore_fields) { %i[id id created_at updated_at] }
|
11
|
+
it { is_expected.to match_array %w[id created_at updated_at] }
|
17
12
|
end
|
18
13
|
end
|
19
14
|
|
20
|
-
describe "#
|
15
|
+
describe "#create_params_for_approval" do
|
21
16
|
let(:book) { build :book }
|
22
17
|
let(:result) { book.attributes.except("id", "created_at", "updated_at") }
|
23
18
|
|
24
|
-
subject { book.
|
19
|
+
subject { book.create_params_for_approval }
|
20
|
+
it { is_expected.to eq result }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#update_params_for_approval" do
|
24
|
+
let(:book) { create(:book).tap { |book| book.name = "changed name" } }
|
25
|
+
let(:result) { { "name" => "changed name" } }
|
26
|
+
|
27
|
+
subject { book.update_params_for_approval }
|
25
28
|
it { is_expected.to eq result }
|
26
29
|
end
|
27
30
|
end
|
data/spec/models/comment_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
RSpec.describe Approval::Comment, type: :model do
|
4
4
|
it { is_expected.to belong_to(:request).class_name("Approval::Request").inverse_of(:comments) }
|
5
|
-
it { is_expected.to belong_to(:user).class_name(
|
5
|
+
it { is_expected.to belong_to(:user).class_name("User") }
|
6
6
|
|
7
7
|
it { is_expected.to validate_presence_of(:content) }
|
8
8
|
it { is_expected.to validate_length_of(:content).is_at_most(Approval.config.comment_maximum) }
|
@@ -9,13 +9,23 @@ RSpec.describe Approval::RequestForm::Update do
|
|
9
9
|
subject { form.save }
|
10
10
|
|
11
11
|
context "when records is single" do
|
12
|
-
let(:records)
|
12
|
+
let(:records) do
|
13
|
+
book = create(:book)
|
14
|
+
book.name = "changed name"
|
15
|
+
book
|
16
|
+
end
|
17
|
+
|
13
18
|
it { expect { subject }.not_to raise_error }
|
14
19
|
it { expect { subject }.to change { Approval::Item.count }.from(0).to(1) }
|
15
20
|
end
|
16
21
|
|
17
22
|
context "when records is multiple" do
|
18
|
-
let(:records)
|
23
|
+
let(:records) do
|
24
|
+
books = create_list(:book, 3)
|
25
|
+
books.map.with_index { |book, i| book.name = "changed name #{i}" }
|
26
|
+
books
|
27
|
+
end
|
28
|
+
|
19
29
|
it { expect { subject }.not_to raise_error }
|
20
30
|
it { expect { subject }.to change { Approval::Item.count }.from(0).to(3) }
|
21
31
|
end
|
data/spec/models/request_spec.rb
CHANGED
@@ -2,8 +2,8 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
RSpec.describe Approval::Request, type: :model do
|
4
4
|
describe "Association" do
|
5
|
-
it { is_expected.to belong_to(:request_user).class_name(
|
6
|
-
it { is_expected.to belong_to(:respond_user).class_name(
|
5
|
+
it { is_expected.to belong_to(:request_user).class_name("User") }
|
6
|
+
it { is_expected.to belong_to(:respond_user).class_name("User") }
|
7
7
|
it { is_expected.to have_many(:comments).class_name("::Approval::Comment").dependent(:destroy) }
|
8
8
|
it { is_expected.to have_many(:items).class_name("::Approval::Item").dependent(:destroy) }
|
9
9
|
end
|
@@ -12,7 +12,6 @@ RSpec.describe Approval::Request, type: :model do
|
|
12
12
|
|
13
13
|
describe "Validation" do
|
14
14
|
it { is_expected.to validate_presence_of(:state) }
|
15
|
-
it { is_expected.to validate_presence_of(:request_user) }
|
16
15
|
it { is_expected.to validate_presence_of(:comments) }
|
17
16
|
it { is_expected.to validate_presence_of(:items) }
|
18
17
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: approval
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yoshiyuki Hirano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|