to_api 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/to_api/version.rb +1 -1
- data/lib/to_api.rb +111 -57
- data/spec/to_api_spec.rb +84 -18
- metadata +4 -4
data/lib/to_api/version.rb
CHANGED
data/lib/to_api.rb
CHANGED
@@ -1,32 +1,80 @@
|
|
1
|
+
module ToApiSelf
|
2
|
+
def to_api(*includes)
|
3
|
+
self
|
4
|
+
end
|
5
|
+
end
|
6
|
+
[ Fixnum, String, DateTime, Date, Time, NilClass ].each do |klass|
|
7
|
+
klass.send(:include, ToApiSelf)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ToApiInstanceMethods
|
11
|
+
def build_to_api_include_hash(*includes)
|
12
|
+
include_hash = {}
|
13
|
+
includes.each do |i|
|
14
|
+
if i.kind_of?(Hash)
|
15
|
+
i.each do |k,v|
|
16
|
+
include_hash[k] = v
|
17
|
+
end
|
18
|
+
else
|
19
|
+
include_hash[i] = []
|
20
|
+
end
|
21
|
+
end
|
22
|
+
include_hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ToApiFilter
|
27
|
+
def add_to_api_filter(include_name, &block)
|
28
|
+
@_to_api_filters ||= {}
|
29
|
+
@_to_api_filters[include_name] = block
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_api_filters=(filters)
|
33
|
+
@_to_api_filters = filters
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_api_filters
|
37
|
+
@_to_api_filters ||={}
|
38
|
+
@_to_api_filters
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
1
42
|
if Object.const_defined? :ActiveRecord
|
43
|
+
|
2
44
|
class ActiveRecord::Base
|
45
|
+
include ToApiFilter
|
46
|
+
|
3
47
|
def to_api(*includes) #assumes all attribute types are fine
|
4
48
|
hash = {}
|
5
|
-
valid_includes = (self.class.reflect_on_all_associations.map(&:name).map(&:to_s) | self.valid_api_includes)
|
49
|
+
valid_includes = (self.class.reflect_on_all_associations.map(&:name).map(&:to_s) | self.valid_api_includes | self.attributes.keys)
|
6
50
|
|
7
|
-
include_hash =
|
8
|
-
|
9
|
-
if
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
else
|
14
|
-
include_hash[i.to_s] = []
|
51
|
+
include_hash = build_to_api_ar_include_hash(*includes)
|
52
|
+
include_hash.keys.each do |inc|
|
53
|
+
if to_api_filters.has_key?(inc)
|
54
|
+
child_includes = include_hash.delete(inc) || []
|
55
|
+
hash[inc] = to_api_filters[inc].call self, child_includes
|
15
56
|
end
|
16
57
|
end
|
17
|
-
|
58
|
+
|
18
59
|
include_hash.delete_if{|k,v| !valid_includes.include?(k.to_s)}
|
19
|
-
|
20
60
|
to_api_attributes.each do |k, v|
|
21
|
-
|
22
|
-
|
23
|
-
|
61
|
+
unless hash[k]
|
62
|
+
v.to_api_filters = to_api_filters if v.respond_to? :to_api_filters
|
63
|
+
|
64
|
+
attribute_includes = include_hash[k] || []
|
65
|
+
to_api_v = v.to_api(*[attribute_includes].flatten.compact)
|
66
|
+
hash[k] = to_api_v
|
67
|
+
end
|
24
68
|
end
|
25
69
|
|
26
|
-
(include_hash.keys-
|
27
|
-
|
28
|
-
|
29
|
-
|
70
|
+
(include_hash.keys-to_api_attributes.keys).each do |relation|
|
71
|
+
unless hash[relation]
|
72
|
+
relation_includes = include_hash[relation] || []
|
73
|
+
api_obj = self.send(relation)
|
74
|
+
api_obj.to_api_filters = to_api_filters if api_obj.respond_to? :to_api_filters
|
75
|
+
|
76
|
+
hash[relation.to_s] = api_obj.respond_to?(:to_api) ? api_obj.to_api(*[relation_includes].flatten.compact) : api_obj
|
77
|
+
end
|
30
78
|
end
|
31
79
|
|
32
80
|
hash
|
@@ -40,58 +88,69 @@ if Object.const_defined? :ActiveRecord
|
|
40
88
|
def to_api_attributes
|
41
89
|
attributes
|
42
90
|
end
|
91
|
+
|
92
|
+
private
|
93
|
+
def build_to_api_ar_include_hash(*includes)
|
94
|
+
include_hash = {}
|
95
|
+
includes.each do |i|
|
96
|
+
if i.kind_of?(Hash)
|
97
|
+
i.each do |k,v|
|
98
|
+
include_hash[k.to_s] = v
|
99
|
+
end
|
100
|
+
else
|
101
|
+
include_hash[i.to_s] = []
|
102
|
+
end
|
103
|
+
end
|
104
|
+
include_hash
|
105
|
+
end
|
106
|
+
|
43
107
|
end
|
44
108
|
|
45
109
|
#Sadly, Scope isn't enumerable
|
46
110
|
class ActiveRecord::NamedScope::Scope
|
111
|
+
include ToApiFilter
|
47
112
|
def to_api(*includes)
|
48
|
-
map{|e|
|
113
|
+
map{|e|
|
114
|
+
e.to_api_filters = to_api_filters if e.respond_to? :to_api_filters
|
115
|
+
e.to_api(*includes)
|
116
|
+
}
|
49
117
|
end
|
50
118
|
end
|
51
119
|
end
|
52
120
|
|
53
|
-
|
54
|
-
|
55
|
-
map{|e|e.to_api(*includes)}
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class Fixnum
|
121
|
+
class Array
|
122
|
+
include ToApiFilter
|
60
123
|
def to_api(*includes)
|
61
|
-
|
62
|
-
|
63
|
-
end
|
124
|
+
map{|e|
|
125
|
+
e.to_api_filters = to_api_filters if e.respond_to? :to_api_filters
|
64
126
|
|
65
|
-
|
66
|
-
|
67
|
-
self
|
127
|
+
e.to_api(*includes)
|
128
|
+
}
|
68
129
|
end
|
69
130
|
end
|
70
131
|
|
71
|
-
class
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class Date
|
132
|
+
class Hash
|
133
|
+
include ToApiFilter
|
134
|
+
include ToApiInstanceMethods
|
78
135
|
def to_api(*includes)
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
136
|
+
values = {}
|
82
137
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
138
|
+
include_hash = build_to_api_include_hash(*includes)
|
139
|
+
|
140
|
+
include_hash.keys.each do |inc|
|
141
|
+
if to_api_filters.has_key?(inc)
|
142
|
+
child_includes = include_hash[inc]
|
143
|
+
values[inc] = to_api_filters[inc].call self, child_includes
|
144
|
+
end
|
145
|
+
end
|
88
146
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
147
|
+
(keys-values.keys).each do |k|
|
148
|
+
val = self[k]
|
149
|
+
val.to_api_filters = to_api_filters if val.respond_to? :to_api_filters
|
150
|
+
child_includes = include_hash[k] || []
|
151
|
+
values[k] = val.to_api(*[child_includes].flatten.compact)
|
94
152
|
end
|
153
|
+
values
|
95
154
|
end
|
96
155
|
end
|
97
156
|
|
@@ -101,8 +160,3 @@ class Symbol
|
|
101
160
|
end
|
102
161
|
end
|
103
162
|
|
104
|
-
class NilClass
|
105
|
-
def to_api(*includes)
|
106
|
-
self
|
107
|
-
end
|
108
|
-
end
|
data/spec/to_api_spec.rb
CHANGED
@@ -8,6 +8,8 @@ class FakeRecord < ActiveRecord::Base
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class OtherFakeRecord < FakeRecord
|
11
|
+
def attributes;{"my_field"=>''};end
|
12
|
+
def my_field;'yar';end
|
11
13
|
end
|
12
14
|
|
13
15
|
class FakeChildRecord < FakeRecord
|
@@ -35,8 +37,8 @@ describe '#to_api' do
|
|
35
37
|
|
36
38
|
it "passes on includes" do
|
37
39
|
a = "a"
|
38
|
-
a.should_receive(:to_api).with(
|
39
|
-
{:one => a}.to_api(['bar']).should == {:one => :apiz}
|
40
|
+
a.should_receive(:to_api).with('bar').and_return(:apiz)
|
41
|
+
{:one => a}.to_api(:one => ['bar']).should == {:one => :apiz}
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
@@ -108,22 +110,6 @@ describe '#to_api' do
|
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
111
|
-
describe Enumerable do
|
112
|
-
class Enumz
|
113
|
-
attr_accessor :kid
|
114
|
-
include Enumerable
|
115
|
-
def each
|
116
|
-
yield @kid
|
117
|
-
end
|
118
|
-
end
|
119
|
-
it "returns to_api of its kids" do
|
120
|
-
e = Enumz.new
|
121
|
-
e.kid = "a"
|
122
|
-
e.kid.should_receive(:to_api).and_return(:apiz)
|
123
|
-
[e.kid].to_api.should == [:apiz]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
113
|
describe ActiveRecord::NamedScope::Scope do
|
128
114
|
it "returns to_api of its kids" do
|
129
115
|
FakeRecord.should_receive(:reflect_on_all_associations).and_return([mock(:name => "fake_child_records")])
|
@@ -182,6 +168,10 @@ describe '#to_api' do
|
|
182
168
|
it "includes the to_api'd attributes" do
|
183
169
|
@base.to_api["age"].should == :apid_age
|
184
170
|
end
|
171
|
+
|
172
|
+
it "allows the inclusion of attributes" do
|
173
|
+
@base.to_api("my_field")["my_field"].should == 'yar'
|
174
|
+
end
|
185
175
|
end
|
186
176
|
|
187
177
|
describe "with includes" do
|
@@ -258,8 +248,84 @@ describe '#to_api' do
|
|
258
248
|
@base.to_api("fake_child_records" => "foopy_pantz").should == {"fake_child_records" => [{}]}
|
259
249
|
end
|
260
250
|
end
|
251
|
+
|
252
|
+
describe "#add_to_api_filter" do
|
253
|
+
it "adds a filter" do
|
254
|
+
@base = OtherFakeRecord.new
|
255
|
+
@base.should_not_receive(:my_field)
|
256
|
+
@base.add_to_api_filter("my_field") do |parent, child_includes|
|
257
|
+
"YO-HO-HO"
|
258
|
+
end
|
259
|
+
|
260
|
+
@base.to_api("my_field")["my_field"].should == "YO-HO-HO"
|
261
|
+
end
|
262
|
+
|
263
|
+
it "sends filter to child" do
|
264
|
+
FakeRecord.stub!(:reflect_on_all_associations => [mock(:name => "kids")])
|
265
|
+
FakeChildRecord.stub!(:reflect_on_all_associations => [mock(:name => "foopy_pantz")])
|
266
|
+
|
267
|
+
@base = FakeRecord.new
|
268
|
+
@base.stub!(:attributes => {})
|
269
|
+
|
270
|
+
@child = FakeChildRecord.new
|
271
|
+
|
272
|
+
@child.stub!(:foopy_pantz => "pantz of foop")
|
273
|
+
|
274
|
+
@base.should_receive(:kids).and_return([@child])
|
275
|
+
|
276
|
+
@base.add_to_api_filter("foopy_pantz") do |parent, child_includes|
|
277
|
+
"kachaa"
|
278
|
+
end
|
279
|
+
|
280
|
+
@base.to_api("kids" => "foopy_pantz").should == {"kids" => [{"foopy_pantz" => "kachaa"}]}
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe "#add_to_api_filter" do
|
287
|
+
before do
|
288
|
+
@subhash = {:b => :c, :d => :e}
|
289
|
+
@hash = {:a => @subhash}
|
261
290
|
end
|
262
291
|
|
292
|
+
it "puts blocks return value in for filtered key" do
|
293
|
+
@hash.add_to_api_filter("count") do |parent, child_includes|
|
294
|
+
@hash.count
|
295
|
+
end
|
296
|
+
|
297
|
+
@hash.to_api("count")["count"].should == 1
|
298
|
+
end
|
299
|
+
|
300
|
+
it "nests hashes with filters" do
|
301
|
+
@hash.add_to_api_filter("id") do |parent, child_includes|
|
302
|
+
parent.object_id
|
303
|
+
end
|
304
|
+
|
305
|
+
api_object = @hash.to_api({"id" => "", :a => "id"})
|
306
|
+
api_object["id"].should == @hash.object_id
|
307
|
+
api_object[:a]["id"].should == @subhash.object_id
|
308
|
+
end
|
309
|
+
|
310
|
+
it "nests hashes of hashes with filters" do
|
311
|
+
@hash.add_to_api_filter("id") do |parent, child_includes|
|
312
|
+
parent.object_id
|
313
|
+
end
|
314
|
+
|
315
|
+
api_object = @hash.to_api({"id" => "", :a => {"id" => ""}})
|
316
|
+
api_object["id"].should == @hash.object_id
|
317
|
+
api_object[:a]["id"].should == @subhash.object_id
|
318
|
+
end
|
319
|
+
|
320
|
+
it "nests hashes with filters with hash params" do
|
321
|
+
@hash.add_to_api_filter("id") do |parent, child_includes|
|
322
|
+
parent.object_id
|
323
|
+
end
|
324
|
+
|
325
|
+
api_object = @hash.to_api(:a => "id")
|
326
|
+
api_object["id"].should be_nil
|
327
|
+
api_object[:a]["id"].should == @subhash.object_id
|
328
|
+
end
|
263
329
|
end
|
264
330
|
end
|
265
331
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: to_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 2
|
10
|
+
version: 1.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Shawn Anderson
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-01-
|
19
|
+
date: 2011-01-18 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|