restpack-resource 0.0.4 → 0.0.5
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/Gemfile.lock
CHANGED
@@ -16,7 +16,7 @@ module RestPack
|
|
16
16
|
paged_resource = {
|
17
17
|
:page => page.pager.current_page,
|
18
18
|
:page_count => page.pager.total_pages,
|
19
|
-
:
|
19
|
+
:count => page.pager.total,
|
20
20
|
:previous_page => page.pager.previous_page,
|
21
21
|
:next_page => page.pager.next_page
|
22
22
|
}
|
@@ -25,7 +25,7 @@ module RestPack
|
|
25
25
|
|
26
26
|
unless page.empty?
|
27
27
|
options[:includes].each do |association|
|
28
|
-
paged_resource
|
28
|
+
add_side_loads(paged_resource, page, association)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -39,7 +39,7 @@ module RestPack
|
|
39
39
|
options[:scope].all(:conditions => options[:filters]).page(options[:page], :order => order)
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def add_side_loads(paged_resource, page, association)
|
43
43
|
target_model_name = association.to_s.singularize.capitalize
|
44
44
|
relationships = self.relationships.select {|r| r.target_model.to_s == target_model_name }
|
45
45
|
raise InvalidInclude if relationships.empty?
|
@@ -47,18 +47,30 @@ module RestPack
|
|
47
47
|
side_loaded_entities = []
|
48
48
|
|
49
49
|
relationships.each do |relationship|
|
50
|
-
|
50
|
+
if relationship.is_a? DataMapper::Associations::ManyToOne::Relationship
|
51
|
+
side_loaded_entities += page.map do |entity| #TODO: GJ: PERF: we can bypass datamapper associations and get by a list of ids instead
|
52
|
+
relation = entity.send(relationship.name.to_sym)
|
53
|
+
relation ? relation.to_resource : nil
|
54
|
+
end
|
55
|
+
elsif relationship.is_a? DataMapper::Associations::OneToMany::Relationship
|
56
|
+
parent_key_name = relationship.parent_key.first.name
|
57
|
+
child_key_name = relationship.child_key.first.name
|
58
|
+
foreign_keys = page.map {|e| e.send(parent_key_name)}.uniq
|
59
|
+
|
60
|
+
#TODO: GJ: configurable side-load page size
|
61
|
+
children = relationship.child_model.all(child_key_name.to_sym => foreign_keys).page({ per_page: 100 })
|
62
|
+
side_loaded_entities += children.map { |c| c.to_resource }
|
63
|
+
|
64
|
+
count_key = "#{relationship.child_model_name.downcase}_count".to_sym
|
65
|
+
paged_resource[count_key] = children.pager.total
|
66
|
+
else
|
51
67
|
raise InvalidInclude, "#{self.name}.#{relationship.name} can't be included when paging #{self.name.pluralize.downcase}"
|
52
68
|
end
|
53
|
-
side_loaded_entities += page.map do |entity| #TODO: GJ: PERF: we can bypass datamapper associations and get by a list of ids instead
|
54
|
-
relation = entity.send(relationship.name.to_sym)
|
55
|
-
relation ? relation.to_resource : nil
|
56
|
-
end
|
57
|
-
side_loaded_entities.uniq!
|
58
|
-
side_loaded_entities.compact!
|
59
69
|
end
|
60
70
|
|
61
|
-
side_loaded_entities
|
71
|
+
side_loaded_entities.uniq!
|
72
|
+
side_loaded_entities.compact!
|
73
|
+
paged_resource[association] = side_loaded_entities
|
62
74
|
end
|
63
75
|
|
64
76
|
def resource_collection_name
|
@@ -12,12 +12,12 @@ describe RestPack::Resource do
|
|
12
12
|
|
13
13
|
it "should return the total count" do
|
14
14
|
result = Song.paged_resource()
|
15
|
-
result[:
|
15
|
+
result[:count].should == 12
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should filter results" do
|
19
19
|
result = Song.paged_resource(artist_id: @artist.id)
|
20
|
-
result[:
|
20
|
+
result[:count].should == 3
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -11,7 +11,7 @@ describe RestPack::Resource do
|
|
11
11
|
it "should return an empty array" do
|
12
12
|
result = Song.paged_resource()
|
13
13
|
result.should_not == nil
|
14
|
-
result[:songs].
|
14
|
+
result[:songs].should == []
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -23,7 +23,7 @@ describe RestPack::Resource do
|
|
23
23
|
it "has a valid first page" do
|
24
24
|
result = Artist.paged_resource()
|
25
25
|
result[:page].should == 1
|
26
|
-
result[:
|
26
|
+
result[:count].should == 16
|
27
27
|
result[:page_count].should == 2
|
28
28
|
result[:previous_page].should == nil
|
29
29
|
result[:next_page].should == 2
|
@@ -38,51 +38,67 @@ describe RestPack::Resource do
|
|
38
38
|
result[:artists].size.should == 6
|
39
39
|
end
|
40
40
|
|
41
|
-
context "when
|
42
|
-
it "should not allow invalid relations" do
|
43
|
-
expect do
|
44
|
-
Artist.paged_resource(:includes => 'invalid_relations')
|
45
|
-
end.to raise_error(RestPack::Resource::InvalidInclude, "Artist.invalid_relations is not an includable relation")
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should not allow includes that have not been specified with 'resource_can_include' NEW" do
|
49
|
-
expect do
|
50
|
-
Comment.paged_resource(:includes => 'songs')
|
51
|
-
end.to raise_error(RestPack::Resource::InvalidInclude, "Comment.songs is not an includable relation")
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should not allow a 'has_many' include when paging" do
|
55
|
-
expect do
|
56
|
-
Artist.paged_resource(:includes => 'songs')
|
57
|
-
end.to raise_error(RestPack::Resource::InvalidInclude, "Artist.songs can't be included when paging artists")
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should return related entities from a 'belongs_to' relationship" do
|
61
|
-
result = Song.paged_resource(:includes => 'artists')
|
62
|
-
result.should_not == nil
|
63
|
-
result[:artists].should_not == nil
|
64
|
-
result[:artists].size.should == 10
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should allow multiple includes" do
|
68
|
-
result = Song.paged_resource(:includes => 'artists,users')
|
69
|
-
result.should_not == nil
|
70
|
-
result[:artists].should_not == nil
|
71
|
-
result[:artists].size.should == 10
|
72
|
-
result[:users].size.should == 20
|
73
|
-
end
|
74
|
-
|
41
|
+
context "when side-loading" do
|
75
42
|
it "should return related entities with their #to_resource representation" do
|
76
43
|
result = Song.paged_resource(:includes => 'users')
|
77
44
|
result[:users][0][:custom].should == 'This is custom data'
|
78
45
|
end
|
79
|
-
|
46
|
+
|
80
47
|
context "when specifying overrides" do
|
81
48
|
it "should give overrides precidence" do
|
82
49
|
result = Artist.paged_resource({ page: 2 }, { page: 3 })
|
83
50
|
result[:page].should == 3
|
84
51
|
end
|
85
52
|
end
|
53
|
+
|
54
|
+
it "should not allow invalid relations" do
|
55
|
+
expect do
|
56
|
+
Artist.paged_resource(:includes => 'invalid_relations')
|
57
|
+
end.to raise_error(RestPack::Resource::InvalidInclude, "Artist.invalid_relations is not an includable relation")
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
context "ManyToOne" do
|
62
|
+
it "should not allow includes that have not been specified with 'resource_can_include'" do
|
63
|
+
expect do
|
64
|
+
Comment.paged_resource(:includes => 'songs')
|
65
|
+
end.to raise_error(RestPack::Resource::InvalidInclude, "Comment.songs is not an includable relation")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return related entities from a 'belongs_to' relationship" do
|
69
|
+
result = Song.paged_resource(:includes => 'artists')
|
70
|
+
result.should_not == nil
|
71
|
+
result[:artists].should_not == nil
|
72
|
+
result[:artists].size.should == 10
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should allow multiple includes" do
|
76
|
+
result = Song.paged_resource(:includes => 'artists,users')
|
77
|
+
result.should_not == nil
|
78
|
+
result[:artists].should_not == nil
|
79
|
+
result[:artists].size.should == 10
|
80
|
+
result[:users].size.should == 20
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
context "OneToMany" do
|
86
|
+
before(:each) do
|
87
|
+
@artist_with_two_songs = Artist.first
|
88
|
+
create(:song, artist: @artist_with_two_songs)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return related entities from a 'has n' relationship" do
|
92
|
+
result = Artist.paged_resource(:includes => 'songs')
|
93
|
+
result.should_not == nil
|
94
|
+
result[:songs].should_not == nil
|
95
|
+
result[:songs].size.should == 11
|
96
|
+
|
97
|
+
result[:songs].select { |song| song.artist == @artist_with_two_songs }.length.should == 2
|
98
|
+
result[:song_count].should == 11
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
86
102
|
end
|
87
103
|
end
|
88
104
|
end
|
@@ -18,23 +18,23 @@ describe RestPack::Resource do
|
|
18
18
|
|
19
19
|
it "should default to ascending" do
|
20
20
|
result = Artist.paged_resource(:sort_by => :id)
|
21
|
-
result[:
|
21
|
+
result[:count].should == Artist.count
|
22
22
|
result[:artists].first[:id].should == 1
|
23
23
|
result[:artists].last[:id].should == 10
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should allow sort_direction of descending" do
|
27
27
|
result = Artist.paged_resource(:sort_by => :id, :sort_direction => :descending)
|
28
|
-
result[:
|
28
|
+
result[:count].should == Artist.count
|
29
29
|
result[:artists].first[:id].should == 20
|
30
30
|
result[:artists].last[:id].should == 11
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should allow sort_by and sort_direction to be string or symbol" do
|
34
34
|
result = Artist.paged_resource(:sort_by => 'id', :sort_direction => 'descending')
|
35
|
-
result[:
|
35
|
+
result[:count].should == Artist.count
|
36
36
|
result = Artist.paged_resource(:sort_by => :id, :sort_direction => :descending)
|
37
|
-
result[:
|
37
|
+
result[:count].should == Artist.count
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restpack-resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
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-02-
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|