restpack-resource 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/restpack-resource/resource/filterable.rb +1 -0
- data/lib/restpack-resource/resource/includable.rb +1 -1
- data/lib/restpack-resource/resource/pageable.rb +1 -1
- data/lib/restpack-resource/resource/single.rb +47 -5
- data/lib/restpack-resource/version.rb +1 -1
- data/spec/resource/single_spec.rb +26 -0
- data/spec/spec_helper.rb +8 -0
- metadata +3 -3
data/Gemfile.lock
CHANGED
@@ -14,7 +14,7 @@ module RestPack
|
|
14
14
|
end
|
15
15
|
def resource_validate_includes!(includes)
|
16
16
|
includes.each do |include|
|
17
|
-
unless self.resource_includable_associations.include?(include)
|
17
|
+
unless self.resource_includable_associations.include?(include.to_sym)
|
18
18
|
raise InvalidInclude, "#{self.name}.#{include} is not an includable relation"
|
19
19
|
end
|
20
20
|
end
|
@@ -119,7 +119,7 @@ module RestPack
|
|
119
119
|
def resource_validate_options!(options)
|
120
120
|
self.resource_validate_includes! options[:includes]
|
121
121
|
self.resource_validate_filters! options[:filters]
|
122
|
-
self.resource_validate_sort_by! options[:sort_by]
|
122
|
+
self.resource_validate_sort_by! options[:sort_by]
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module RestPack
|
2
2
|
module Resource
|
3
|
+
#NOTE: GJ: this need a great big refactor
|
3
4
|
module Single
|
4
5
|
def single_resource(params = {}, overrides = {})
|
5
6
|
options = build_single_options(params, overrides)
|
@@ -11,7 +12,49 @@ module RestPack
|
|
11
12
|
def get_single_resource(options)
|
12
13
|
model = self.get(options[:id])
|
13
14
|
|
14
|
-
|
15
|
+
raise "404" unless model #TODO: GJ: decide on error handling / status
|
16
|
+
resource = model_as_resource(model)
|
17
|
+
|
18
|
+
options[:includes].each do |association|
|
19
|
+
add_single_side_loads(resource, model, association)
|
20
|
+
end
|
21
|
+
|
22
|
+
resource
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_single_side_loads(resource, model, association)
|
26
|
+
target_model_name = association.to_s.singularize.capitalize
|
27
|
+
|
28
|
+
relationships = self.relationships.select {|r| r.target_model.to_s == target_model_name }
|
29
|
+
raise InvalidInclude if relationships.empty?
|
30
|
+
|
31
|
+
side_loaded_entities = []
|
32
|
+
|
33
|
+
relationships.each do |relationship|
|
34
|
+
if relationship.is_a? DataMapper::Associations::ManyToOne::Relationship
|
35
|
+
relation = model.send(relationship.name.to_sym)
|
36
|
+
|
37
|
+
side_loaded_entities << (relation ? model_as_resource(relation) : nil)
|
38
|
+
elsif relationship.is_a? DataMapper::Associations::OneToMany::Relationship
|
39
|
+
parent_key_name = relationship.parent_key.first.name
|
40
|
+
child_key_name = relationship.child_key.first.name
|
41
|
+
foreign_key = model.send(parent_key_name)
|
42
|
+
|
43
|
+
#TODO: GJ: configurable side-load page size
|
44
|
+
children = relationship.child_model.all(child_key_name.to_sym => foreign_key).page({ per_page: 100 })
|
45
|
+
side_loaded_entities += children.map { |c| model_as_resource(c) }
|
46
|
+
|
47
|
+
count_key = "#{relationship.child_model_name.downcase}_count".to_sym
|
48
|
+
resource[count_key] = children.pager.total
|
49
|
+
else
|
50
|
+
raise InvalidInclude, "#{self.name}.#{relationship.name} can't be included when paging #{self.name.pluralize.downcase}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
side_loaded_entities.uniq!
|
55
|
+
side_loaded_entities.compact!
|
56
|
+
|
57
|
+
resource[association] = side_loaded_entities
|
15
58
|
end
|
16
59
|
|
17
60
|
def build_single_options(params, overrides)
|
@@ -23,13 +66,12 @@ module RestPack
|
|
23
66
|
options.reverse_merge!( #defaults
|
24
67
|
:includes => []
|
25
68
|
)
|
26
|
-
|
69
|
+
|
27
70
|
raise InvalidArguments, "id must be specified" unless params[:id]
|
28
71
|
|
29
|
-
|
30
|
-
|
72
|
+
resource_normalise_options!(options)
|
73
|
+
resource_validate_options!(options)
|
31
74
|
#TODO: GJ: other validations
|
32
|
-
|
33
75
|
options
|
34
76
|
end
|
35
77
|
end
|
@@ -12,11 +12,37 @@ describe RestPack::Resource do
|
|
12
12
|
end.to raise_error(RestPack::Resource::InvalidArguments, "id must be specified")
|
13
13
|
end
|
14
14
|
|
15
|
+
pending "handles unfound ids"
|
16
|
+
|
15
17
|
it "return correct model #as_resource" do
|
16
18
|
result = Song.single_resource({ :id => @song.id })
|
17
19
|
result[:id].should == @song.id
|
18
20
|
result[:url].should == "/api/v1/songs/#{@song.id}"
|
19
21
|
end
|
22
|
+
|
23
|
+
it "sideloads ManyToOne" do
|
24
|
+
result = Song.single_resource(:id => @song.id, :includes => 'artists')
|
25
|
+
result[:id].should == @song.id
|
26
|
+
|
27
|
+
result[:artists].should_not == nil
|
28
|
+
result[:artists].count.should == 1
|
29
|
+
result[:artists][0][:url].should == "/api/v1/artists/#{@song.artist.id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "OneToMany" do
|
33
|
+
before(:each) do
|
34
|
+
@artist = create(:artist)
|
35
|
+
3.times { create(:song, :artist => @artist) }
|
36
|
+
end
|
37
|
+
|
38
|
+
it "sideloads OneToMany relations" do
|
39
|
+
result = Artist.single_resource(:id => @artist.id, :includes => 'songs')
|
40
|
+
result[:id].should == @artist.id
|
41
|
+
|
42
|
+
result[:songs].should_not == nil
|
43
|
+
result[:songs].count.should == 3
|
44
|
+
end
|
45
|
+
end
|
20
46
|
|
21
47
|
end
|
22
48
|
end
|
data/spec/spec_helper.rb
CHANGED
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.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -104,7 +104,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
104
|
version: '0'
|
105
105
|
segments:
|
106
106
|
- 0
|
107
|
-
hash:
|
107
|
+
hash: 1427584335195097292
|
108
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
109
|
none: false
|
110
110
|
requirements:
|
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
113
|
version: '0'
|
114
114
|
segments:
|
115
115
|
- 0
|
116
|
-
hash:
|
116
|
+
hash: 1427584335195097292
|
117
117
|
requirements: []
|
118
118
|
rubyforge_project:
|
119
119
|
rubygems_version: 1.8.25
|