action_callback 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/Gemfile +0 -1
- data/README.md +82 -0
- data/action_callback.gemspec +1 -1
- data/lib/action_callback.rb +9 -3
- data/lib/action_callback/callback.rb +16 -31
- data/lib/action_callback/define_callback.rb +5 -5
- data/lib/action_callback/define_validation.rb +41 -0
- data/lib/action_callback/validation.rb +39 -0
- data/lib/action_callback/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2308622a7b13b58904071fd5c6190d5b3433988
|
4
|
+
data.tar.gz: c65e93d23b37e7690a18c621f835fad5785434c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 555276c5220445cf130f7998f79e1684c9ee945ac4042149874b5bb68e118ed3407e4cc16d598fa14fdc270d55c27f225a58e3ed6dad722cc71c9c8232c32065
|
7
|
+
data.tar.gz: ccb8a7d7f36eae991d0458bbb77c94af7e45758aa52746586cab0be8cbe6bbf9988f57c3b696ceebfaa313cdb25d1b9d30cec9fb45635bc8cfa8f746314a3d53
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/action_callback.svg)](https://badge.fury.io/rb/action_callback)
|
2
|
+
[![security](https://hakiri.io/github/EdmundLeex/action_callback/master.svg)](https://hakiri.io/github/EdmundLeex/action_callback/master)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/EdmundLeex/action_callback/badges/gpa.svg)](https://codeclimate.com/github/EdmundLeex/action_callback)
|
1
4
|
[![Build Status](https://travis-ci.org/EdmundLeex/action_callback.svg?branch=master)](https://travis-ci.org/EdmundLeex/action_callback)
|
2
5
|
|
3
6
|
# CallbackAction
|
@@ -20,8 +23,87 @@ Or install it yourself as:
|
|
20
23
|
|
21
24
|
$ gem install callback_action
|
22
25
|
|
26
|
+
## Preliminary
|
27
|
+
|
28
|
+
- Ruby >= 2.1.0
|
29
|
+
- Rails >= 4.2.6
|
30
|
+
|
23
31
|
## Usage
|
24
32
|
|
33
|
+
### 1. `validate`
|
34
|
+
|
35
|
+
#### In Rails
|
36
|
+
|
37
|
+
This gem adds a `before` option to the `validate` method.
|
38
|
+
Use it on any of your model's method. Simply add custom validation method just
|
39
|
+
like you usually do.
|
40
|
+
|
41
|
+
- It runs the method if validation is good
|
42
|
+
- Otherwise, it returns false (if there is any error)
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
class Car < ActiveRecord::Base
|
46
|
+
validate :key_present, before: [:unlock_door]
|
47
|
+
|
48
|
+
def unlock_door
|
49
|
+
# unlock the door
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def key_present
|
55
|
+
unless has_key? && valid_key?
|
56
|
+
errors.add(:base, 'need the right key')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
car = Car.new
|
62
|
+
car.unlock_door
|
63
|
+
# If has_key?
|
64
|
+
# - do whatever the method does
|
65
|
+
# - return whatever it returns
|
66
|
+
# If !has_key?
|
67
|
+
# - returns false
|
68
|
+
# - car.errors.full_messages => ['need the right key']
|
69
|
+
```
|
70
|
+
|
71
|
+
At the same time, it preserves the default `validate` logic if `before` option is
|
72
|
+
not used.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
class Car < ActiveRecord::Base
|
76
|
+
validate :valid_vin_number
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
#### In Plain Ruby
|
81
|
+
|
82
|
+
This gem adds a `validate` method to classes that extend this module. You should
|
83
|
+
raise error in the validator method
|
84
|
+
|
85
|
+
- It execute the method if validation passes.
|
86
|
+
- It raises the error you specify in the validator method, and stop there.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
class Car
|
90
|
+
extend ActionCallback
|
91
|
+
validate :key_present, before: [:unlock_door]
|
92
|
+
|
93
|
+
def unlock_door
|
94
|
+
# unlock the door
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def key_present
|
100
|
+
fail 'key invalid' unless valid_key?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
### 2. `before_action` / `after_action`
|
106
|
+
|
25
107
|
If you are using Rails, in your Active Record models:
|
26
108
|
|
27
109
|
```ruby
|
data/action_callback.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = 'Add callbacks to your ActiveRecord models or plain Ruby classes'
|
10
10
|
spec.description = "Here you can add callbacks to your models using `before_action`, `after_action`"
|
11
11
|
|
12
|
-
spec.required_ruby_version = ">= 2.
|
12
|
+
spec.required_ruby_version = ">= 2.1.0"
|
13
13
|
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/action_callback.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "./action_callback/version"
|
2
|
+
require_relative "./action_callback/define_callback"
|
3
|
+
require_relative "./action_callback/callback"
|
4
|
+
require_relative "./action_callback/define_validation"
|
5
|
+
require_relative "./action_callback/validation"
|
4
6
|
|
5
7
|
module ActionCallback
|
6
8
|
include Callback
|
9
|
+
include Validation
|
7
10
|
extend self
|
8
11
|
|
9
12
|
def ActionCallback.extended(mod)
|
@@ -13,6 +16,9 @@ module ActionCallback
|
|
13
16
|
define_callback(callback)
|
14
17
|
alias_method :"#{callback}_filter", :"#{callback}_action"
|
15
18
|
end
|
19
|
+
|
20
|
+
initialize_validation_chain(mod)
|
21
|
+
define_validation
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
@@ -1,54 +1,39 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
3
|
module Callback
|
4
|
-
|
5
|
-
|
6
|
-
# each of those keys points to an array of callbacks
|
7
|
-
# {
|
8
|
-
# method: {
|
9
|
-
# before: [...],
|
10
|
-
# after: [...]
|
11
|
-
# }
|
12
|
-
# }
|
4
|
+
HOOKS = [:before, :after].freeze
|
5
|
+
|
13
6
|
class Chain
|
14
|
-
|
7
|
+
HOOKS.each do |cb_hook|
|
8
|
+
define_method("#{cb_hook}_chain_of") do |mth_name|
|
9
|
+
get_hook(cb_hook, mth_name)
|
10
|
+
end
|
11
|
+
end
|
15
12
|
|
16
13
|
def initialize
|
17
|
-
|
14
|
+
HOOKS.each do |cb_hook|
|
18
15
|
instance_variable_set("@_#{cb_hook}_chain", new_chain)
|
19
16
|
end
|
20
17
|
end
|
21
18
|
|
22
|
-
def
|
23
|
-
chain = get_chain(
|
24
|
-
chain[mth] <<
|
25
|
-
end
|
26
|
-
|
27
|
-
CALLBACK_HOOK.each do |cb_hook|
|
28
|
-
define_method("#{cb_hook}_chain_of") do |mth_name|
|
29
|
-
get_callbacks(cb_hook, mth_name)
|
30
|
-
end
|
19
|
+
def append(hook_name, mth, hook_mth)
|
20
|
+
chain = get_chain(hook_name)
|
21
|
+
chain[mth] << hook_mth
|
31
22
|
end
|
32
23
|
|
33
24
|
private
|
34
25
|
|
35
|
-
def
|
36
|
-
chain = get_chain(
|
26
|
+
def get_hook(hook_name, mth)
|
27
|
+
chain = get_chain(hook_name)
|
37
28
|
chain[mth].dup
|
38
29
|
end
|
39
30
|
|
40
|
-
def get_chain(
|
41
|
-
instance_variable_get("@_#{
|
31
|
+
def get_chain(hook_name)
|
32
|
+
instance_variable_get("@_#{hook_name}_chain")
|
42
33
|
end
|
43
34
|
|
44
35
|
def new_chain
|
45
|
-
Hash.new { |h, k| h[k] =
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class << self
|
50
|
-
def get_callbacks(mth)
|
51
|
-
@_callback_chain.get_callbacks[mth]
|
36
|
+
Hash.new { |h, k| h[k] = Set.new }
|
52
37
|
end
|
53
38
|
end
|
54
39
|
end
|
@@ -2,19 +2,19 @@ module ActionCallback
|
|
2
2
|
private
|
3
3
|
|
4
4
|
def initialize_callback_chain(mod)
|
5
|
-
mod.instance_variable_set('@_callback_chain', Callback::Chain.new)
|
6
|
-
|
7
5
|
mod.define_singleton_method(:_callback_chain) do
|
8
|
-
|
6
|
+
@_callback_chain
|
9
7
|
end
|
10
8
|
end
|
11
9
|
|
12
10
|
def define_callback(callback_hook)
|
13
11
|
define_method("#{callback_hook}_action") do |callback, method_scope|
|
12
|
+
@_callback_chain ||= Callback::Chain.new
|
13
|
+
|
14
14
|
method_scope[:on].each do |mth_name|
|
15
|
-
|
15
|
+
_callback_chain.append(callback_hook, mth_name, callback)
|
16
16
|
|
17
|
-
undef_method(mth_name) if
|
17
|
+
undef_method(mth_name) if included_modules.map(&:to_s).include?('ActionWithCallbacks')
|
18
18
|
|
19
19
|
class_eval <<-RUBY
|
20
20
|
module ActionWithCallbacks
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ActionCallback
|
2
|
+
private
|
3
|
+
|
4
|
+
def initialize_validation_chain(mod)
|
5
|
+
mod.define_singleton_method(:_validation_chain) do
|
6
|
+
@_validation_chain
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_validation
|
11
|
+
define_method(:validate) do |*args, &block|
|
12
|
+
@_validation_chain ||= Validation::Chain.new
|
13
|
+
|
14
|
+
options = args.last
|
15
|
+
if options.key?(:before)
|
16
|
+
validator_mth_name = args.first
|
17
|
+
options[:before].each do |mth_name|
|
18
|
+
_validation_chain.append(:before, mth_name, validator_mth_name)
|
19
|
+
undef_method(mth_name) if included_modules.map(&:to_s).include?('ActionWithValidations')
|
20
|
+
|
21
|
+
class_eval <<-RUBY
|
22
|
+
module ActionWithValidations
|
23
|
+
define_method(:#{mth_name}) do |*args, &block|
|
24
|
+
self.class._validation_chain.before_chain_of(:#{mth_name}).each { |v| send(v) }
|
25
|
+
|
26
|
+
should_run = true
|
27
|
+
should_run = !errors.present? if self.class.ancestors.include?(ActiveRecord::Base)
|
28
|
+
|
29
|
+
super(*args, &block) if should_run
|
30
|
+
end
|
31
|
+
end
|
32
|
+
RUBY
|
33
|
+
|
34
|
+
prepend self::ActionWithValidations
|
35
|
+
end
|
36
|
+
else
|
37
|
+
super(*args, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Validation
|
4
|
+
HOOKS = [:before].freeze
|
5
|
+
|
6
|
+
class Chain
|
7
|
+
HOOKS.each do |cb_hook|
|
8
|
+
define_method("#{cb_hook}_chain_of") do |mth_name|
|
9
|
+
get_hook(cb_hook, mth_name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
HOOKS.each do |cb_hook|
|
15
|
+
instance_variable_set("@_#{cb_hook}_chain", new_chain)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def append(hook_name, mth, hook_mth)
|
20
|
+
chain = get_chain(hook_name)
|
21
|
+
chain[mth] << hook_mth
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def get_hook(hook_name, mth)
|
27
|
+
chain = get_chain(hook_name)
|
28
|
+
chain[mth].dup
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_chain(hook_name)
|
32
|
+
instance_variable_get("@_#{hook_name}_chain")
|
33
|
+
end
|
34
|
+
|
35
|
+
def new_chain
|
36
|
+
Hash.new { |h, k| h[k] = Set.new }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_callback
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edmund Li
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,6 +72,8 @@ files:
|
|
72
72
|
- lib/action_callback.rb
|
73
73
|
- lib/action_callback/callback.rb
|
74
74
|
- lib/action_callback/define_callback.rb
|
75
|
+
- lib/action_callback/define_validation.rb
|
76
|
+
- lib/action_callback/validation.rb
|
75
77
|
- lib/action_callback/version.rb
|
76
78
|
homepage: https://github.com/EdmundLeex/action_callback
|
77
79
|
licenses:
|
@@ -85,7 +87,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
87
|
requirements:
|
86
88
|
- - ">="
|
87
89
|
- !ruby/object:Gem::Version
|
88
|
-
version: 2.
|
90
|
+
version: 2.1.0
|
89
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
92
|
requirements:
|
91
93
|
- - ">="
|
@@ -93,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
95
|
version: '0'
|
94
96
|
requirements: []
|
95
97
|
rubyforge_project:
|
96
|
-
rubygems_version: 2.
|
98
|
+
rubygems_version: 2.5.2
|
97
99
|
signing_key:
|
98
100
|
specification_version: 4
|
99
101
|
summary: Add callbacks to your ActiveRecord models or plain Ruby classes
|