restful_serializer 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/restful.rb +5 -0
- data/lib/restful/serializer.rb +83 -45
- data/lib/restful/version.rb +1 -1
- data/spec/restful_spec.rb +4 -0
- data/spec/serializer_spec.rb +31 -13
- metadata +4 -4
data/lib/restful.rb
CHANGED
@@ -124,6 +124,11 @@ module Restful
|
|
124
124
|
# Route prefix for api calls.
|
125
125
|
mattr_accessor :api_prefix
|
126
126
|
|
127
|
+
# Default url options for ActionController::UrlWriter.
|
128
|
+
# (Generally you must provide {:host => 'example.com'})
|
129
|
+
mattr_accessor :default_url_options
|
130
|
+
self.default_url_options = {}
|
131
|
+
|
127
132
|
# Hash for configuration Restful models.
|
128
133
|
mattr_accessor :model_configuration
|
129
134
|
self.model_configuration = {}
|
data/lib/restful/serializer.rb
CHANGED
@@ -3,27 +3,55 @@ require 'deep_merge'
|
|
3
3
|
|
4
4
|
module Restful
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
6
|
+
# Used to construct and attempt to call named routes by providing resource
|
7
|
+
# strings out of which a named route method name will be constructed:
|
8
|
+
#
|
9
|
+
# Options:
|
10
|
+
#
|
11
|
+
# * :resources => a symbol, string or array of same describing segments of
|
12
|
+
# the helper method name. e.g. [:user, :comments] => user_comments (to
|
13
|
+
# which _url will be appended...)
|
14
|
+
# * :method => overrides the use of :resources and :prefix
|
15
|
+
# * :args => any arguments to be passed to the named_route when it is called
|
16
|
+
#
|
17
|
+
# = Example
|
18
|
+
#
|
19
|
+
# Url.for(:resources => [:user, :comments], :args => 1)
|
20
|
+
# # => send("#{Restful.api_prefix}_user_comments_url", 1)
|
21
|
+
# # which if it exists is likely to return something like:
|
22
|
+
# # "http://example.com/user/1/comments"
|
23
|
+
#
|
24
|
+
class Url
|
25
|
+
include ActionController::UrlWriter
|
26
|
+
@@initialized = false
|
27
|
+
|
28
|
+
attr_accessor :options
|
29
|
+
|
30
|
+
class << self
|
31
|
+
|
32
|
+
# Sets ActionController::UrlWriter.default_url_options from Restful.default_url_options.
|
33
|
+
# Attempting to do this during Rails initialization results in botched routing, presumably
|
34
|
+
# because of how ActionController::UrlWriter initializes when you include it into a class.
|
35
|
+
# So this method is called lazily.
|
36
|
+
def initialize_default_url_options
|
37
|
+
unless @@initialized
|
38
|
+
self.default_url_options = Restful.default_url_options
|
39
|
+
@@initialized = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Helper for generating url strings from resource options.
|
44
|
+
def for(options)
|
45
|
+
new(options).to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(options)
|
50
|
+
self.options = options
|
51
|
+
Url.initialize_default_url_options
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
27
55
|
url_for = [options[:method], 'url'] if options.include?(:method)
|
28
56
|
url_for ||= [Restful.api_prefix, options[:resources], 'url'].flatten.compact
|
29
57
|
url_for = url_for.join('_').downcase
|
@@ -32,21 +60,33 @@ module Restful
|
|
32
60
|
|
33
61
|
end
|
34
62
|
|
35
|
-
|
36
|
-
|
37
|
-
include UrlForHelpers
|
38
|
-
attr_accessor :subject, :base_klass, :klass, :options, :shallow
|
39
|
-
|
40
|
-
class << self
|
63
|
+
# Provides some utility functions for acting deeply on hashes.
|
64
|
+
class DeepHash < ::Hash
|
41
65
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
66
|
+
class << self
|
67
|
+
def deeply_stringify_keys!(object)
|
68
|
+
case object
|
69
|
+
when ::Hash
|
70
|
+
then
|
71
|
+
object.stringify_keys!
|
72
|
+
recurse_on = object.values
|
73
|
+
when Array then recurse_on = object
|
74
|
+
end
|
75
|
+
recurse_on.each do |member|
|
76
|
+
deeply_stringify_keys!(member)
|
77
|
+
end if recurse_on
|
78
|
+
return object
|
48
79
|
end
|
49
80
|
end
|
81
|
+
|
82
|
+
# Walks the graph, and destructively applies stringify_keys!
|
83
|
+
def deeply_stringify_keys!
|
84
|
+
return DeepHash.deeply_stringify_keys!(self)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class Serializer
|
89
|
+
attr_accessor :subject, :base_klass, :klass, :options, :shallow
|
50
90
|
|
51
91
|
def initialize(subject, *args)
|
52
92
|
self.subject = subject
|
@@ -109,9 +149,9 @@ module Restful
|
|
109
149
|
|
110
150
|
def href
|
111
151
|
unless @href
|
112
|
-
@href =
|
113
|
-
@href =
|
114
|
-
@href =
|
152
|
+
@href = Url.for(:method => options[:url_for], :args => subject.id) if options.include?(:url_for)
|
153
|
+
@href = Url.for(:resources => klass, :args => subject.id) unless @href
|
154
|
+
@href = Url.for(:resources => base_klass, :args => subject.id) unless @href || base_klass == klass
|
115
155
|
end
|
116
156
|
return @href
|
117
157
|
end
|
@@ -119,16 +159,16 @@ module Restful
|
|
119
159
|
private
|
120
160
|
|
121
161
|
def _serialize_active_record
|
122
|
-
restful =
|
123
|
-
klass => ActiveRecord::Serialization::Serializer.new(subject, active_record_serialization_options).serializable_record
|
124
|
-
|
162
|
+
restful = DeepHash[
|
163
|
+
klass => ActiveRecord::Serialization::Serializer.new(subject, active_record_serialization_options).serializable_record
|
164
|
+
]
|
125
165
|
restful['name'] = name if name
|
126
166
|
restful['href'] = href
|
127
167
|
associations.each do |association|
|
128
168
|
restful["#{association.name}_href"] = association.href
|
129
169
|
end unless shallow
|
130
170
|
|
131
|
-
return restful
|
171
|
+
return restful.deeply_stringify_keys!
|
132
172
|
end
|
133
173
|
|
134
174
|
def _serialize_array
|
@@ -143,8 +183,6 @@ module Restful
|
|
143
183
|
|
144
184
|
# Handle for information about an ActiveRecord association.
|
145
185
|
class Association
|
146
|
-
include ActionController::UrlWriter
|
147
|
-
include UrlForHelpers
|
148
186
|
attr_accessor :name, :association_name, :association, :subject, :subject_klass
|
149
187
|
|
150
188
|
def initialize(subject, subject_klass, association_name, name = nil)
|
@@ -161,7 +199,7 @@ module Restful
|
|
161
199
|
|
162
200
|
def href
|
163
201
|
if singular?
|
164
|
-
href =
|
202
|
+
href = Url.for(:resources => association_name, :args => subject.send(association.name).id)
|
165
203
|
else
|
166
204
|
href = collective_href
|
167
205
|
end
|
@@ -170,8 +208,8 @@ module Restful
|
|
170
208
|
|
171
209
|
def collective_href
|
172
210
|
# try url_for nested resources first
|
173
|
-
unless href =
|
174
|
-
href =
|
211
|
+
unless href = Url.for(:resources => [subject_klass, association_name], :args => subject.id)
|
212
|
+
href = Url.for(:resources => association_name)
|
175
213
|
end
|
176
214
|
return href
|
177
215
|
end
|
data/lib/restful/version.rb
CHANGED
data/spec/restful_spec.rb
CHANGED
@@ -8,6 +8,10 @@ describe Restful do
|
|
8
8
|
Restful.api_prefix.should == 'foo'
|
9
9
|
end
|
10
10
|
|
11
|
+
it "should have a default_url_options accessor" do
|
12
|
+
Restful.default_url_options.should == {}
|
13
|
+
end
|
14
|
+
|
11
15
|
it "should have a model_configuration accessor" do
|
12
16
|
Restful.model_configuration.should == {}
|
13
17
|
end
|
data/spec/serializer_spec.rb
CHANGED
@@ -69,7 +69,7 @@ describe Restful::Serializer do
|
|
69
69
|
|
70
70
|
before(:each) do
|
71
71
|
@foo = Foo.new(:name => 'A foo')
|
72
|
-
Restful
|
72
|
+
Restful.default_url_options = { :host => 'test.org' }
|
73
73
|
end
|
74
74
|
|
75
75
|
after(:each) do
|
@@ -99,14 +99,6 @@ describe Restful::Serializer do
|
|
99
99
|
rs.klass.should == 'foo'
|
100
100
|
end
|
101
101
|
|
102
|
-
it "should set default url options" do
|
103
|
-
Restful::Serializer.default_url_options.should == { :host => 'test.org' }
|
104
|
-
Restful::Association.default_url_options.should == { :host => 'test.org' }
|
105
|
-
Restful::Serializer.default_url_options = opts = { :host => 'foo' }
|
106
|
-
Restful::Serializer.default_url_options.should == opts
|
107
|
-
Restful::Association.default_url_options.should == opts
|
108
|
-
end
|
109
|
-
|
110
102
|
it "should serialize" do
|
111
103
|
@foo.save!
|
112
104
|
rs = Restful::Serializer.new(@foo)
|
@@ -139,7 +131,7 @@ describe Restful::Serializer do
|
|
139
131
|
'name' => @foo.fancy_name,
|
140
132
|
'foo' => {
|
141
133
|
'name' => @foo.name,
|
142
|
-
|
134
|
+
'a_method' => @foo.a_method,
|
143
135
|
},
|
144
136
|
'href' => "http://test.org/prefix/foos/#{@foo.id}",
|
145
137
|
}
|
@@ -169,7 +161,7 @@ describe Restful::Serializer do
|
|
169
161
|
'foo' => {
|
170
162
|
'id' => @foo.id,
|
171
163
|
'name' => @foo.name,
|
172
|
-
|
164
|
+
'a_method' => @foo.a_method,
|
173
165
|
},
|
174
166
|
'href' => "http://test.org/prefix/foos/#{@foo.id}",
|
175
167
|
}
|
@@ -285,7 +277,7 @@ describe Restful::Serializer do
|
|
285
277
|
'name' => @bar1.name,
|
286
278
|
'bar' => {
|
287
279
|
'name' => @bar1.name,
|
288
|
-
|
280
|
+
'dingos' => [
|
289
281
|
{ 'name' => @dingo1.name, 'id' => @dingo1.id, },
|
290
282
|
{ 'name' => @dingo2.name, 'id' => @dingo2.id, },
|
291
283
|
],
|
@@ -298,7 +290,7 @@ describe Restful::Serializer do
|
|
298
290
|
'name' => @bar2.name,
|
299
291
|
'bar' => {
|
300
292
|
'name' => @bar2.name,
|
301
|
-
|
293
|
+
'dingos' => [
|
302
294
|
{ 'name' => @dingo3.name, 'id' => @dingo3.id, },
|
303
295
|
{ 'name' => @dingo4.name, 'id' => @dingo4.id, },
|
304
296
|
],
|
@@ -399,3 +391,29 @@ describe Restful::Serializer do
|
|
399
391
|
end
|
400
392
|
end
|
401
393
|
end
|
394
|
+
|
395
|
+
describe Restful::DeepHash do
|
396
|
+
it "should deeply stringify keys" do
|
397
|
+
h = Restful::DeepHash[
|
398
|
+
:foo => {
|
399
|
+
:bar => 1
|
400
|
+
},
|
401
|
+
:members => [
|
402
|
+
{ :id => 1 },
|
403
|
+
{ :id => 2 },
|
404
|
+
]
|
405
|
+
]
|
406
|
+
h2 = h.deeply_stringify_keys!
|
407
|
+
h.should == {
|
408
|
+
'foo' => {
|
409
|
+
'bar' => 1,
|
410
|
+
},
|
411
|
+
'members' => [
|
412
|
+
{ 'id' => 1 },
|
413
|
+
{ 'id' => 2 },
|
414
|
+
],
|
415
|
+
}
|
416
|
+
h.should equal(h2)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restful_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Josh Partlow
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-19 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|