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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a4abe852096e06e5583e4cfcca4d52602849ffe
4
- data.tar.gz: 1e60d8d0f4af193dbddab6afcd3de35cacb52873
3
+ metadata.gz: e2308622a7b13b58904071fd5c6190d5b3433988
4
+ data.tar.gz: c65e93d23b37e7690a18c621f835fad5785434c5
5
5
  SHA512:
6
- metadata.gz: b7c228312cf98559c0820a580a7e21e9f2156083e659a36835621aeed54cc023b3692338695c0a93e43d093e645c4adee90b8806c83fcd44b4636daeeb714b48
7
- data.tar.gz: 97c9fc56abc6318928644dffd38e305e110830b55726161af12e0a755b382effc8572dfb04b43c33ee142c74afe9ebfa5fd0b9763a61890dfa79909c72bb4a7f
6
+ metadata.gz: 555276c5220445cf130f7998f79e1684c9ee945ac4042149874b5bb68e118ed3407e4cc16d598fa14fdc270d55c27f225a58e3ed6dad722cc71c9c8232c32065
7
+ data.tar.gz: ccb8a7d7f36eae991d0458bbb77c94af7e45758aa52746586cab0be8cbe6bbf9988f57c3b696ceebfaa313cdb25d1b9d30cec9fb45635bc8cfa8f746314a3d53
data/.gitignore CHANGED
@@ -8,4 +8,6 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  *.gem
11
- *.log
11
+ *.log
12
+ .ruby-version
13
+ .DS_Store
data/Gemfile CHANGED
@@ -5,6 +5,5 @@ gemspec
5
5
  group :test do
6
6
  gem "sqlite3"
7
7
  gem 'minitest-reporters'
8
- gem 'minitest-debugger'
9
8
  gem 'rails', '4.0.0'
10
9
  end
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
@@ -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.0.0"
12
+ spec.required_ruby_version = ">= 2.1.0"
13
13
 
14
14
  spec.license = "MIT"
15
15
 
@@ -1,9 +1,12 @@
1
- require "action_callback/version"
2
- require "action_callback/define_callback"
3
- require "action_callback/callback"
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
- # The chain should have each method that has callback as key
5
- # and each callback points to a hash with :before, :after as key
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
- CALLBACK_HOOK = [:before, :after].freeze
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
- CALLBACK_HOOK.each do |cb_hook|
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 append_callback(callback_hook, mth, callback)
23
- chain = get_chain(callback_hook)
24
- chain[mth] << callback
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 get_callbacks(callback_hook, mth)
36
- chain = get_chain(callback_hook)
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(callback_hook)
41
- instance_variable_get("@_#{callback_hook}_chain")
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
- instance_variable_get('@_callback_chain')
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
- @_callback_chain.append_callback(callback_hook, mth_name, callback)
15
+ _callback_chain.append(callback_hook, mth_name, callback)
16
16
 
17
- undef_method(mth_name) if method_defined?(mth_name)
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
@@ -1,5 +1,5 @@
1
1
  module ActionCallback
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
 
4
4
  def self.version
5
5
  VERSION
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.2.1
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-08 00:00:00.000000000 Z
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.0.0
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.6.8
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