collection_extensions 0.0.1 → 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.
- data/.travis.yml +0 -4
- data/Gemfile +2 -0
- data/README.md +35 -22
- data/lib/collection_extensions.rb +21 -14
- data/lib/collection_extensions/version.rb +1 -1
- data/spec/collection_extensions_spec.rb +45 -47
- metadata +2 -2
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# CollectionExtensions
|
2
2
|
|
3
3
|
Sometimes an operation just doesn't fit well into a scope, but you don't want to lose your declarative code style
|
4
|
-
by operating on all the objects individually. This gem adds a few lines of code to make it easier to add methods
|
4
|
+
by operating on all the objects individually. This gem adds a few lines of code to make it easier to add methods
|
5
|
+
to collections of ActiveRecord objects.
|
5
6
|
|
6
7
|
<img src="https://secure.travis-ci.org/arches/collection_extensions.png" />
|
7
8
|
|
@@ -9,44 +10,56 @@ by operating on all the objects individually. This gem adds a few lines of code
|
|
9
10
|
|
10
11
|
Add this line to your application's Gemfile:
|
11
12
|
|
12
|
-
|
13
|
+
```ruby
|
14
|
+
gem 'collection_extensions'
|
15
|
+
```
|
13
16
|
|
14
17
|
And then execute:
|
15
18
|
|
16
|
-
|
19
|
+
```bash
|
20
|
+
$ bundle
|
21
|
+
```
|
17
22
|
|
18
23
|
Or install it yourself as:
|
19
24
|
|
20
|
-
|
25
|
+
```bash
|
26
|
+
$ gem install collection_extensions
|
27
|
+
```
|
21
28
|
|
22
29
|
## Usage
|
23
30
|
|
24
|
-
|
31
|
+
A collections of records will be extended based on the naming convention `%sCollectionExtensions`, where the `%s` substitution
|
32
|
+
is the camel-cased name of the class. For example, collections of User objects will be extended with the methods in the
|
33
|
+
`UserCollectionExtensions` model and collections of BlogPost objects will be extended with the methods in the `BlogPostCollectionExtensions`
|
34
|
+
module.
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
has_many :orders, :preferences
|
29
|
-
extend_collections :orders, :preferences
|
30
|
-
|
31
|
-
# the original unextended collection is still available, aliased as orig_* (eg, orig_orders or orig_preferences)
|
32
|
-
end
|
33
|
-
|
34
|
-
This will use the modules OrdersCollectionExtensions and PreferencesCollectionExtensions to extend those associations
|
35
|
-
whenever you use them. For example:
|
36
|
+
```ruby
|
37
|
+
module BlogPostCollectionExtensions
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
# hash key is user ID, hash value is the number of comments they've posted on this set of blog posts
|
40
|
+
def comments_per_user
|
41
|
+
comment_counts = {}
|
42
|
+
|
43
|
+
# 'self' is the array of blog posts
|
44
|
+
each do |blog_post|
|
45
|
+
blog_post.comments.each do |comment|
|
46
|
+
comment_counts[comment.user_id] ||= 0
|
47
|
+
comment_counts[comment.user_id] += 1
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
44
|
-
|
51
|
+
comment_counts
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
45
55
|
|
46
|
-
|
56
|
+
### Naming Convention
|
47
57
|
|
48
|
-
|
58
|
+
If you want a different naming convention, set the config variable using `%s` string substitution:
|
49
59
|
|
60
|
+
```ruby
|
61
|
+
CollectionExtensions::Config.naming_convention = "MethodsForCollectionsOf%s"
|
62
|
+
```
|
50
63
|
|
51
64
|
## Contributing
|
52
65
|
|
@@ -1,25 +1,32 @@
|
|
1
1
|
require "collection_extensions/version"
|
2
2
|
require "collection_extensions/cattr"
|
3
3
|
require "collection_extensions/config"
|
4
|
+
require "active_record"
|
4
5
|
|
5
|
-
|
6
|
+
class ActiveRecord::Relation
|
7
|
+
alias :orig_to_a :to_a
|
8
|
+
alias :orig_method_missing :method_missing
|
6
9
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
+
def to_a
|
11
|
+
records = orig_to_a
|
12
|
+
|
13
|
+
records.extend extension_module if extension_module
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
Array(associations).each do |association|
|
14
|
-
alias_method "orig_#{association}", association
|
15
|
+
records
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
18
|
+
def extension_module
|
19
|
+
extension_klass = CollectionExtensions::Config.naming_convention % @klass.to_s
|
20
|
+
if Object.constants.include? extension_klass.to_sym
|
21
|
+
Object.const_get(extension_klass)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def method_missing(method, *args, &block)
|
26
|
+
if extension_module and extension_module.method_defined? method
|
27
|
+
to_a.send(method, *args, &block)
|
28
|
+
else
|
29
|
+
orig_method_missing(method, *args, &block)
|
30
|
+
end
|
31
|
+
end
|
25
32
|
end
|
@@ -1,69 +1,67 @@
|
|
1
|
+
require 'active_record'
|
1
2
|
require 'collection_extensions'
|
2
3
|
|
3
|
-
module
|
4
|
-
def
|
5
|
-
"
|
4
|
+
module UserCollectionExtensions
|
5
|
+
def utest
|
6
|
+
"ufoo"
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
|
-
module
|
10
|
-
def operate_on_all_foobars
|
11
|
-
"operate_on_all_foobars"
|
12
|
-
end
|
10
|
+
module ExtensionMethodsForUserCollections
|
13
11
|
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
"
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
class CollectionTester
|
22
|
-
include CollectionExtensions
|
23
|
-
|
24
|
-
def examples
|
25
|
-
"original examples method"
|
13
|
+
describe "#extension_class" do
|
14
|
+
context "when the extension module exists" do
|
15
|
+
it "returns the constant" do
|
16
|
+
r = ActiveRecord::Relation.new :User, :users
|
17
|
+
r.extension_module.should == UserCollectionExtensions
|
18
|
+
end
|
26
19
|
end
|
27
20
|
|
28
|
-
|
29
|
-
"
|
21
|
+
context "when the extension module doesn't exist" do
|
22
|
+
it "returns nil" do
|
23
|
+
r = ActiveRecord::Relation.new :Order, :orders
|
24
|
+
r.extension_module.should be_nil
|
25
|
+
end
|
30
26
|
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
describe CollectionExtensions do
|
36
|
-
let(:ct) { CollectionTester.new }
|
28
|
+
context "when the naming convention has been changed" do
|
29
|
+
before { CollectionExtensions::Config.naming_convention = "ExtensionMethodsForUserCollections" }
|
30
|
+
after { CollectionExtensions::Config.naming_convention = CollectionExtensions::Config::DEFAULT_NAMING_CONVENTION }
|
37
31
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
ct.examples.should be_a ExamplesCollectionExtensions
|
42
|
-
ct.examples.operate_on_all_examples.should == "operate_on_all_examples"
|
43
|
-
end
|
44
|
-
|
45
|
-
it "aliases the foobars" do
|
46
|
-
ct.orig_foobars.should == "original foobars method"
|
47
|
-
ct.foobars.should be_a FoobarsCollectionExtensions
|
48
|
-
ct.foobars.operate_on_all_foobars.should == "operate_on_all_foobars"
|
32
|
+
it "uses the proper convention to return the constant" do
|
33
|
+
r = ActiveRecord::Relation.new :User, :users
|
34
|
+
r.extension_module.should == ExtensionMethodsForUserCollections
|
49
35
|
end
|
50
36
|
end
|
51
37
|
end
|
52
38
|
|
53
|
-
describe "
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
39
|
+
describe "calling methods on the array" do
|
40
|
+
it "pulls extension methods from the module" do
|
41
|
+
r = ActiveRecord::Relation.new :User, :users
|
42
|
+
r.stub(orig_to_a: [])
|
43
|
+
r.to_a.utest.should == "ufoo"
|
58
44
|
end
|
45
|
+
end
|
59
46
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
47
|
+
describe "calling methods on the relation" do
|
48
|
+
it "pulls extension methods from the module" do
|
49
|
+
r = ActiveRecord::Relation.new :User, :users
|
50
|
+
r.stub(orig_to_a: [])
|
51
|
+
r.utest.should == "ufoo"
|
64
52
|
end
|
65
|
-
end
|
66
53
|
|
67
|
-
|
54
|
+
it "lets non-extension methods pass through" do
|
55
|
+
r = ActiveRecord::Relation.new :User, :users
|
56
|
+
r.stub(orig_to_a: ['first'])
|
57
|
+
r.first.should == 'first'
|
58
|
+
end
|
68
59
|
|
60
|
+
context "when the extension module doesn't exist" do
|
61
|
+
it "lets methods pass through" do
|
62
|
+
r = ActiveRecord::Relation.new :Order, :orders
|
63
|
+
r.stub(orig_to_a: ['first'])
|
64
|
+
r.first.should == 'first'
|
65
|
+
end
|
66
|
+
end
|
69
67
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collection_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
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: 2012-09-
|
12
|
+
date: 2012-09-05 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: Lightweight framework for adding methods to groups of ActiveRecord objects
|
15
15
|
email:
|