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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- restpack-resource (0.0.8)
4
+ restpack-resource (0.0.9)
5
5
  activesupport (~> 3.2.11)
6
6
  dm-pager (~> 1.1.0)
7
7
 
@@ -13,6 +13,7 @@ module RestPack
13
13
  self.resource_filterable_by += columns
14
14
  end
15
15
  def resource_validate_filters!(filters)
16
+ return unless filters
16
17
  filters.keys.each do |filter|
17
18
  raise InvalidFilter.new unless self.resource_filterable_by.include?(filter)
18
19
  end
@@ -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
- model_as_resource(model)
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
- resource_validate_includes! options[:includes]
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
@@ -1,5 +1,5 @@
1
1
  module RestPack
2
2
  module Resource
3
- VERSION = "0.0.8"
3
+ VERSION = "0.0.9"
4
4
  end
5
5
  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
@@ -33,6 +33,14 @@ class Artist
33
33
 
34
34
  resource_can_include :songs
35
35
  resource_can_sort_by :id, :name
36
+
37
+ def as_resource
38
+ {
39
+ id: id,
40
+ name: name,
41
+ url: "/api/v1/artists/#{id}"
42
+ }
43
+ end
36
44
  end
37
45
 
38
46
  class Song
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.8
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: 840564972735635958
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: 840564972735635958
116
+ hash: 1427584335195097292
117
117
  requirements: []
118
118
  rubyforge_project:
119
119
  rubygems_version: 1.8.25