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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b11eef9bb8afb6a55fefa35bc8fef5132d1908d0
4
- data.tar.gz: 628a25ca361506832c1c709902af993c18c43d59
3
+ metadata.gz: 0f6a5f60b035099e2da46cd42dc3c09deafe3b8a
4
+ data.tar.gz: 920839f43297af114060d06f66f2256a22b2040b
5
5
  SHA512:
6
- metadata.gz: e0a6c2f36e2234bc1c3612f8e6b27886bba1c0bf801ead75bd82c95f8e755ba588641d2107a936b28e5d275ea0d450f2850ebf2e49af7748548769c7b62bc300
7
- data.tar.gz: 0bbd75b3e3e5dbdbbd7fa22e3dc4837134f19e895867293c51a99d0371e03044918e371d91a05e7b1fd4115c559f4a1267da90a54c64076fa5066b5646909a73
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 Post < ApplicationRecord
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 = User.find_or_create_by(email: "staff@example.com")
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 = User.find_or_create_by(email: "staff@example.com")
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).map {|record| record.price *= 0.5 }
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 = User.find_or_create_by(email: "staff@example.com")
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 = User.find_or_create_by(email: "admin@example.com")
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 = User.find_or_create_by(email: "admin@example.com")
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
 
@@ -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
 
@@ -5,7 +5,7 @@ module Approval
5
5
  class_methods do
6
6
  def acts_as_approval_resource(ignore_fields: [])
7
7
  include ::Approval::Mixins::Resource
8
- append_ignore_fields(ignore_fields)
8
+ assign_ignore_fields(ignore_fields)
9
9
  end
10
10
 
11
11
  def acts_as_approval_user
@@ -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 append_ignore_fields(ignore_fields = [])
15
- self.approval_ignore_fields = DEFAULT_IGNORE_FIELDS.dup.concat(ignore_fields).map(&:to_s).uniq
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 params_for_approval
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
@@ -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
@@ -15,6 +15,7 @@ module Approval
15
15
  validates :resource_id, unless: :create_event?
16
16
  validates :resource_type
17
17
  validates :event, inclusion: { in: EVENTS }
18
+ validates :params, if: :update_event?
18
19
  end
19
20
 
20
21
  validate :ensure_resource_be_valid
@@ -2,9 +2,13 @@ module Approval
2
2
  class Request < ::ActiveRecord::Base
3
3
  self.table_name_prefix = "approval_".freeze
4
4
 
5
- with_options class_name: Approval.config.user_class_name do
6
- belongs_to :request_user
7
- belongs_to :respond_user, optional: true
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
- ::ActiveRecord::Base.transaction do
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.params_for_approval,
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
- ::ActiveRecord::Base.transaction do
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|
@@ -4,7 +4,7 @@ module Approval
4
4
  private
5
5
 
6
6
  def prepare
7
- ::ActiveRecord::Base.transaction do
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.params_for_approval,
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
- ::ActiveRecord::Base.transaction do
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
- ::ActiveRecord::Base.transaction do
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
- ::ActiveRecord::Base.transaction do
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)
@@ -1,3 +1,3 @@
1
1
  module Approval
2
- VERSION = "0.2.3".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
@@ -1,7 +1,4 @@
1
1
  Approval.configure do |config|
2
- # Your user model name (e.g. User, AdminUser, Member, default: User)
3
- config.user_class_name = "User"
4
-
5
2
  # Maximum characters of comment for reason (default: 2000)
6
3
  config.comment_maximum = 2000
7
4
 
@@ -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 ".append_ignore_fields" do
7
- subject { described_class.append_ignore_fields(ignore_fields) }
6
+ describe ".assign_ignore_fields" do
7
+ subject { described_class.assign_ignore_fields(ignore_fields) }
8
8
 
9
- context "when ignore_fields are blank" do
10
- let(:ignore_fields) { [] }
11
- it { is_expected.to match_array Approval::Mixins::Resource::DEFAULT_IGNORE_FIELDS }
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 "#params_for_approval" do
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.params_for_approval }
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
@@ -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(Approval.config.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) { create :book }
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) { create_list :book, 3 }
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
@@ -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(Approval.config.user_class_name) }
6
- it { is_expected.to belong_to(:respond_user).class_name(Approval.config.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.2.3
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-01 00:00:00.000000000 Z
11
+ date: 2017-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler