restful_serializer 0.1.2 → 0.1.3
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/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
|