has_many_callbacks 0.0.3 → 0.0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +53 -20
- data/lib/has_many_callbacks.rb +17 -2
- data/lib/has_many_callbacks/version.rb +1 -1
- 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: f90ce44eb6ffe7889b256dc9de088c64bb89a09a
|
4
|
+
data.tar.gz: 25a2972a6594f730d0e72760481bf408e813f916
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 600a38824a6d6e6bd7559f5fba91bcc465e6158ecca63d22c84fd569096e398d49907d30451ee22927092f5b41ef813b1cab0e53885bfe335e04a8aa202e6bba
|
7
|
+
data.tar.gz: da6976393e652c35634b9b9013ff56829e1b6be5e311bffa5df196ea8701723e3dbcef31ec1f5f279b3e1baecb62219e071bb0ce2567922c79fcdc41f35ac278
|
data/README.rdoc
CHANGED
@@ -11,33 +11,66 @@ in the same way.
|
|
11
11
|
|
12
12
|
The main goal is ensuring the code that expresses the relation parent behavior when handling events
|
13
13
|
triggered by child objects is kept in the parent code base, where it belongs. If the parent
|
14
|
-
has a lot of relations, this prevents that class' code to be scattered
|
14
|
+
has a lot of relations, this prevents that class' code to be scattered across all the child
|
15
15
|
class definitions.
|
16
16
|
|
17
|
-
===
|
18
|
-
Consider the following classes:
|
17
|
+
=== Usage
|
19
18
|
|
20
|
-
|
21
|
-
# name, completed
|
22
|
-
has_many :tasks
|
23
|
-
end
|
19
|
+
Just add a reference to Gemfile:
|
24
20
|
|
25
|
-
|
26
|
-
# name, completed
|
27
|
-
belongs_to :todo_list
|
28
|
-
end
|
21
|
+
gem install "has_many_callbacks"
|
29
22
|
|
30
|
-
|
23
|
+
As an example, consider the following classes:
|
31
24
|
|
32
|
-
class TodoList
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
todo_list.save! if todo_list.completed_changed?
|
37
|
-
}
|
25
|
+
class TodoList < ActiveRecord::Base
|
26
|
+
# name, completed
|
27
|
+
has_many :tasks
|
28
|
+
end
|
38
29
|
|
39
|
-
|
30
|
+
class Task < ActiveRecord::Base
|
31
|
+
# name, completed
|
32
|
+
belongs_to :todo_list
|
33
|
+
end
|
34
|
+
|
35
|
+
Imagine that you want a To-Do list to be marked completed if it's not empty and all the tasks in it are completed.
|
36
|
+
|
37
|
+
class TodoList < ActiveRecord::Base
|
38
|
+
has_many :tasks, :inverse_of => :todo_list,
|
39
|
+
:after_save => lambda { |todo_list, task|
|
40
|
+
todo_list.completed = !task.completed ? false : todo_list.tasks.where(:completed => false).count == 0
|
41
|
+
todo_list.save! if todo_list.completed_changed?
|
42
|
+
},
|
43
|
+
:after_destroy => lambda { |todo_list, task|
|
44
|
+
todo_list.completed = (todo_list.tasks.any? and todo_list.tasks.where(:completed => false).count == 0)
|
45
|
+
todo_list.save! if todo_list.completed_changed?
|
46
|
+
}
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
Please note that the <tt>inverse_of</tt> option is required. Three callbacks are available, <tt>after_create</tt>,
|
51
|
+
<tt>after_save</tt> and <tt>after_destroy</tt>.
|
52
|
+
|
53
|
+
You can also pass callbacks as symbols refering to the instance methods to call:
|
54
|
+
|
55
|
+
class TodoList < ActiveRecord::Base
|
56
|
+
has_many :tasks,
|
57
|
+
:inverse_of => :todo_list,
|
58
|
+
:after_save => :handle_task_save,
|
59
|
+
:after_destroy => :handle_task_destroy
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def handle_task_save(task)
|
64
|
+
self.completed = !task.completed ? false : tasks.where(:completed => false).count == 0
|
65
|
+
save! if completed_changed?
|
66
|
+
end
|
67
|
+
|
68
|
+
def handle_task_destroy(task)
|
69
|
+
self.completed = (tasks.any? and tasks.where(:completed => false).count == 0)
|
70
|
+
save! if completed_changed?
|
71
|
+
end
|
72
|
+
end
|
40
73
|
|
41
74
|
|
42
75
|
=== License
|
43
|
-
This software is
|
76
|
+
This software is available under the MIT License. See MIT-LICENSE for details.
|
data/lib/has_many_callbacks.rb
CHANGED
@@ -4,6 +4,10 @@ module HasManyCallbacks
|
|
4
4
|
|
5
5
|
class HasManyWithChildCallbacksBuilder < ActiveRecord::Associations::Builder::HasMany
|
6
6
|
HAS_MANY_CALLBACKS = [ :after_create, :after_save, :after_destroy ]
|
7
|
+
def self.valid_options
|
8
|
+
super + HAS_MANY_CALLBACKS
|
9
|
+
end
|
10
|
+
|
7
11
|
def valid_options
|
8
12
|
super + HAS_MANY_CALLBACKS
|
9
13
|
end
|
@@ -27,7 +31,7 @@ module HasManyCallbacks
|
|
27
31
|
end
|
28
32
|
|
29
33
|
code = %{
|
30
|
-
|
34
|
+
#{callback_name} do |obj|
|
31
35
|
association = obj.class.reflect_on_association(:#{association.inverse_of.name})
|
32
36
|
inverse_association = association.klass.reflect_on_association(:#{association.name})
|
33
37
|
callback_option = inverse_association.options[:#{callback_name}]
|
@@ -54,13 +58,24 @@ module HasManyCallbacks
|
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
61
|
+
|
57
62
|
module ClassMethods
|
63
|
+
end
|
64
|
+
|
65
|
+
module ClassMethodsV4
|
58
66
|
def has_many(name, scope = nil, options = {}, &extension)
|
59
67
|
HasManyWithChildCallbacksBuilder.build(self, name, scope, options, &extension)
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
71
|
+
module ClassMethodsV3
|
72
|
+
def has_many(name, options = {}, &extension)
|
73
|
+
HasManyWithChildCallbacksBuilder.build(self, name, options, &extension)
|
74
|
+
end
|
75
|
+
end
|
63
76
|
end
|
64
77
|
|
78
|
+
module_to_include = ((Rails.version.split('.').first) || 4).to_i == 4 ?
|
79
|
+
HasManyCallbacks::ClassMethodsV4 : HasManyCallbacks::ClassMethodsV3
|
80
|
+
HasManyCallbacks::ClassMethods.send(:include, module_to_include)
|
65
81
|
ActiveRecord::Base.send(:include, HasManyCallbacks)
|
66
|
-
ActiveRecord::Base.send(:include, HasManyCallbacks::ClassMethods)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_many_callbacks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3
|
4
|
+
version: 0.0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jose Fernandes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|