active-record-without-callbacks 0.0.2 → 0.0.3
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.
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "active-record-without-callbacks"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date = "2013-04-
|
12
|
+
s.date = "2013-04-08"
|
13
13
|
s.description = "A method that allows you to run code without callbacks for a specific active-record model."
|
14
14
|
s.email = "kj@gfish.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -1,39 +1,74 @@
|
|
1
|
+
#This class can disable all callbacks for a model, run a block and then re-enable all callbacks.
|
1
2
|
class ActiveRecordWithoutCallbacks
|
2
3
|
TRUE_BLOCK = proc{ true }
|
3
4
|
|
4
|
-
def self.wo_callbacks(
|
5
|
-
|
6
|
-
|
5
|
+
def self.wo_callbacks(args)
|
6
|
+
klass = args[:class]
|
7
|
+
@debug = args[:debug]
|
8
|
+
|
9
|
+
#Callback-types that we will clear or recompile.
|
10
|
+
callbacks = [:create, :find, :initialize, :destroy, :commit, :rollback, :save, :touch, :update, :validate, :validation]
|
11
|
+
callback_types = [:before, :after]
|
12
|
+
previous_values = []
|
7
13
|
|
8
|
-
#
|
9
|
-
|
14
|
+
#List of various possible callbacks.
|
15
|
+
takes = [:_create_callbacks, :_find_callbacks, :_initialize_callbacks, :_destroy_callbacks, :_commit_callbacks, :_rollback_callbacks, :_save_callbacks, :_touch_callbacks, :_update_callbacks, :_validate_callbacks, :_validation_callbacks]
|
10
16
|
|
17
|
+
#Run inside exclusive, so we are sure no other thread suffers from the horrible hack, that we are about to do.
|
11
18
|
Thread.exclusive do
|
12
|
-
|
19
|
+
callbacks.each do |callback|
|
20
|
+
puts "Disabling callbacks for '#{callback}'." if @debug
|
21
|
+
|
22
|
+
#Method-name for callbacks to reset.
|
23
|
+
callbacks_method_name = "_#{callback}_callbacks"
|
24
|
+
|
13
25
|
#Store previous value for restoring later.
|
14
|
-
|
15
|
-
:
|
16
|
-
:value => klass.__send__(
|
26
|
+
previous_values << {
|
27
|
+
:callbacks_method_name => callbacks_method_name,
|
28
|
+
:value => klass.__send__(callbacks_method_name).clone
|
17
29
|
}
|
18
30
|
|
19
31
|
#Clear all callbacks.
|
20
|
-
|
32
|
+
puts "Clearing callbacks in '#{callbacks_method_name}'." if @debug
|
33
|
+
klass.__send__(callbacks_method_name).clear
|
21
34
|
|
22
35
|
#Test that callbacks really was cleared.
|
23
|
-
|
36
|
+
puts "Checking if everything is okay for '#{callback}'." if @debug
|
37
|
+
raise "Expected '#{callbacks_method_name}' to be empty but it wasnt: #{klass.__send__(callbacks_method_name)}" unless klass.__send__(callbacks_method_name).empty?
|
38
|
+
|
39
|
+
#Trick ActiveRecord to recompile callbacks.
|
40
|
+
callback_types.each do |callback_type|
|
41
|
+
method_name = "#{callback_type}_#{callback}"
|
42
|
+
|
43
|
+
if klass.respond_to?(method_name)
|
44
|
+
klass.__send__(method_name, &TRUE_BLOCK)
|
45
|
+
end
|
46
|
+
end
|
24
47
|
end
|
25
48
|
|
26
|
-
klass.after_save(&TRUE_BLOCK)
|
27
|
-
|
28
49
|
begin
|
50
|
+
#Run the given block, now that all callbacks are disabled.
|
51
|
+
puts "Yielding block." if @debug
|
29
52
|
return yield
|
30
53
|
ensure
|
54
|
+
puts "Restoring callbacks." if @debug
|
55
|
+
|
31
56
|
#Restore previous callbacks.
|
32
|
-
|
33
|
-
|
57
|
+
previous_values.each do |previous_value|
|
58
|
+
method_name = "#{previous_value[:callbacks_method_name]}="
|
59
|
+
klass.__send__(method_name, previous_value[:value])
|
34
60
|
end
|
35
61
|
|
36
|
-
|
62
|
+
#Trick ActiveRecord to recompile old callbacks.
|
63
|
+
callbacks.each do |callback|
|
64
|
+
callback_types.each do |callback_type|
|
65
|
+
method_name = "#{callback_type}_#{callback}"
|
66
|
+
|
67
|
+
if klass.respond_to?(method_name)
|
68
|
+
klass.__send__(method_name, &TRUE_BLOCK)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
37
72
|
end
|
38
73
|
end
|
39
74
|
end
|
@@ -2,6 +2,36 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe "ActiveRecordWithoutCallbacks" do
|
4
4
|
it "doesnt fail" do
|
5
|
-
#
|
5
|
+
#The following code tests disabled callbacks.
|
6
|
+
|
7
|
+
#Deal.after_create do
|
8
|
+
# raise "Create WTF!?"
|
9
|
+
#end
|
10
|
+
|
11
|
+
#Deal.after_save do
|
12
|
+
# raise "Save WTF!?"
|
13
|
+
#end
|
14
|
+
|
15
|
+
Deal.before_create do
|
16
|
+
raise "Before create!"
|
17
|
+
end
|
18
|
+
|
19
|
+
Deal.after_create do
|
20
|
+
raise "After create!"
|
21
|
+
end
|
22
|
+
|
23
|
+
ActiveRecordWithoutCallbacks.wo_callbacks(Deal) do
|
24
|
+
deal = Deal.new(:legacy_id => 999999)
|
25
|
+
|
26
|
+
#puts deal.methods.sort
|
27
|
+
|
28
|
+
deal.save! :validate => false
|
29
|
+
puts "Deal created as expected"
|
30
|
+
end
|
31
|
+
|
32
|
+
deal = Deal.new(:legacy_id => 999999999)
|
33
|
+
|
34
|
+
deal.save! :validate => false
|
35
|
+
puts "Second deal creation did not fail."
|
6
36
|
end
|
7
37
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active-record-without-callbacks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -111,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
111
|
version: '0'
|
112
112
|
segments:
|
113
113
|
- 0
|
114
|
-
hash:
|
114
|
+
hash: 1788919925078652095
|
115
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|