association_callbacks 0.3.0 → 1.0.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 +4 -4
- data/.gitignore +5 -5
- data/README.mdown +48 -36
- data/VERSION +1 -1
- data/association_callbacks.gemspec +2 -2
- data/lib/association_callbacks.rb +1 -0
- data/lib/association_callbacks/active_record.rb +10 -8
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2994cec2c46bbf3f85cf7c87164276185678571a
|
4
|
+
data.tar.gz: b0e8f30e500e5cacec58cda454647f9a93775fa4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cce917363779bc6b2c8b4fc5ef7524adf7c516bbcb289514276cc76ed5a935cdbac71090d792c9310e8f0140022b6a2d78028f3595c9cde6ef1e4e6ccea9eb42
|
7
|
+
data.tar.gz: b6e9141678292d4963239b66854236db1d3da84996fe1652b5c8805db2636a8f5eed7d06bcd2e58c08c03f5cafd338f83537edb87851dc11273a45a5c26eb998
|
data/.gitignore
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
.DS_Store
|
2
|
-
|
3
|
-
|
4
|
-
Gemfile.lock
|
5
|
-
pkg
|
6
|
-
spec/test.sqlite3
|
2
|
+
/.bundle/
|
3
|
+
/.ruby-version
|
4
|
+
/Gemfile.lock
|
5
|
+
/pkg/
|
6
|
+
/spec/test.sqlite3
|
data/README.mdown
CHANGED
@@ -8,27 +8,31 @@ model into an associated one.
|
|
8
8
|
|
9
9
|
First, two simple `Article` and `Comment` models:
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
```ruby
|
12
|
+
class Article < ActiveRecord::Base
|
13
|
+
has_many :comments
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
class Comment < ActiveRecord::Base
|
17
|
+
belongs_to :article
|
18
|
+
end
|
19
|
+
```
|
18
20
|
|
19
21
|
Then, you often need to denormalize `Comment` stuff into `Post` or vice versa.
|
20
22
|
Here is the standard way to denormalize `last_comment_at` on posts:
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
+
```ruby
|
25
|
+
class Comment < ActiveRecord::Base
|
26
|
+
belongs_to :article
|
24
27
|
|
25
|
-
|
26
|
-
|
28
|
+
after_create :update_post_last_comment_at
|
29
|
+
after_destroy :update_post_last_comment_at
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def update_post_last_comment_at
|
32
|
+
post.update_attributes!(last_comment_at: post.comments.order('created_at').last.try(:created_at))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
32
36
|
|
33
37
|
But, there is a problem here: we define `Post` denormalization callbacks into
|
34
38
|
`Comment` model. IMHO, this is the wrong place. `Post` denormalization
|
@@ -37,16 +41,18 @@ models.
|
|
37
41
|
|
38
42
|
Here is how to do it with `association_callabacks`:
|
39
43
|
|
40
|
-
|
41
|
-
|
44
|
+
```ruby
|
45
|
+
class Post < ActiveRecord::Base
|
46
|
+
has_many :comments
|
42
47
|
|
43
|
-
|
44
|
-
|
48
|
+
after_create :update_last_comment_at, source: :comments
|
49
|
+
after_destroy :update_last_comment_at, source: :comments
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
51
|
+
def update_last_comment_at
|
52
|
+
update_attributes!(last_comment_at: comments.order('created_at').last.try(:created_at))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
50
56
|
|
51
57
|
You just have to specify `:source` option to your callbacks, and that's all!
|
52
58
|
Note that `:source` option must be an existing association name.
|
@@ -54,25 +60,29 @@ Note that `:source` option must be an existing association name.
|
|
54
60
|
Note that association callbacks methods can take associated record as
|
55
61
|
argument, above code can be:
|
56
62
|
|
57
|
-
|
58
|
-
|
63
|
+
```ruby
|
64
|
+
class Post < ActiveRecord::Base
|
65
|
+
has_many :comments
|
59
66
|
|
60
|
-
|
67
|
+
after_create :update_last_comment_at
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
69
|
+
def update_last_comment_at(comment)
|
70
|
+
update_attributes!(last_comment_at: comment.created_at)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
66
74
|
|
67
75
|
Association callbacks can also be defined as block:
|
68
76
|
|
69
|
-
|
70
|
-
|
77
|
+
```ruby
|
78
|
+
class Post < ActiveRecord::Base
|
79
|
+
has_many :comments
|
71
80
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
81
|
+
after_destroy source: :comments do |post|
|
82
|
+
post.decrement!(:comments_count)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
76
86
|
|
77
87
|
Another solution is to use [ActiveModel Observers](http://api.rubyonrails.org/classes/ActiveModel/Observer.html),
|
78
88
|
but for a better project comprehension, I really prefer placing denormalization
|
@@ -83,7 +93,9 @@ cache sweepers, etc.
|
|
83
93
|
|
84
94
|
Just add this into your `Gemfile`:
|
85
95
|
|
86
|
-
|
96
|
+
```ruby
|
97
|
+
gem 'association_callabacks'
|
98
|
+
```
|
87
99
|
|
88
100
|
Then, just run `bundle install`.
|
89
101
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
s.require_paths = ['lib']
|
18
18
|
|
19
|
-
s.add_dependency 'activerecord', '>=
|
20
|
-
s.add_dependency 'activesupport', '>=
|
19
|
+
s.add_dependency 'activerecord', '>= 5.0.0', '< 5.1.0'
|
20
|
+
s.add_dependency 'activesupport', '>= 5.0.0', '< 5.1.0'
|
21
21
|
|
22
22
|
s.add_development_dependency 'byebug', '>= 3.2.0', '< 3.6.0'
|
23
23
|
s.add_development_dependency 'rake', '>= 10.3.0', '< 10.5.0'
|
@@ -23,22 +23,24 @@ module AssociationCallbacks
|
|
23
23
|
base.class_eval <<-EOS
|
24
24
|
class << self
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
mod = Module.new do
|
27
|
+
def #{callback}(*args, &block)
|
28
|
+
if args.last.is_a?(Hash) && args.last.key?(:source)
|
29
|
+
options = args.extract_options!
|
30
|
+
define_callback_with_association(:#{callback}, args, options, &block)
|
31
|
+
else
|
32
|
+
super(*args, &block)
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
|
-
|
36
|
+
prepend(mod)
|
35
37
|
|
36
38
|
end
|
37
39
|
EOS
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
|
-
|
43
|
+
class_methods do
|
42
44
|
|
43
45
|
private
|
44
46
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: association_callbacks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Toulotte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,40 +16,40 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 5.1.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 5.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 5.1.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 5.0.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
42
|
+
version: 5.1.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 5.0.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
52
|
+
version: 5.1.0
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: byebug
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
173
|
version: '0'
|
174
174
|
requirements: []
|
175
175
|
rubyforge_project: association_callbacks
|
176
|
-
rubygems_version: 2.
|
176
|
+
rubygems_version: 2.5.1
|
177
177
|
signing_key:
|
178
178
|
specification_version: 4
|
179
179
|
summary: Callbacks for ActiveRecord associations
|