restful_serializer 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +4 -1
- data/lib/restful.rb +57 -17
- data/lib/restful/serializer.rb +21 -12
- data/lib/restful/version.rb +1 -1
- data/restful_serializer.gemspec +1 -0
- data/spec/restful_spec.rb +13 -13
- data/spec/serializer_spec.rb +61 -2
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +1 -0
- metadata +22 -6
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@ If the model has a name column, it will be used to describe the resource.
|
|
6
6
|
|
7
7
|
This library does not attempt to provide href info for transitions, or deal much with questions of authorization beyond what is specified in the serialization configuration lines. It assumes that these issues would be resolved in the controller. It assumes standard naming conventions for routes.
|
8
8
|
|
9
|
-
So far only tested with Rails 2.
|
9
|
+
So far only tested with Rails 2.1.0
|
10
10
|
|
11
11
|
== Example
|
12
12
|
|
@@ -73,3 +73,6 @@ Example output:
|
|
73
73
|
# "column1"=>1,
|
74
74
|
# "column2"=>2,}}
|
75
75
|
|
76
|
+
= More Docs
|
77
|
+
|
78
|
+
Please see the Restful rdoc and the specs for more details.
|
data/lib/restful.rb
CHANGED
@@ -5,27 +5,29 @@ require 'restful/serializer'
|
|
5
5
|
# This library is used to decorate ActiveRecord with methods to assist in generating
|
6
6
|
# Restful content for Web Services.
|
7
7
|
#
|
8
|
-
# It produces a hash of reference, object and href information for an
|
9
|
-
# or association. Output is highly configurable both
|
10
|
-
# method calls.
|
8
|
+
# It produces a hash of reference, object and href information for an
|
9
|
+
# ActiveRecord instance or association. Output is highly configurable both
|
10
|
+
# through Rails initialization and method calls.
|
11
11
|
#
|
12
12
|
# = Options
|
13
13
|
#
|
14
|
-
# The following options may be set in the Restful.model_configuration hash on a
|
15
|
-
# basis.
|
14
|
+
# The following options may be set in the Restful.model_configuration hash on a
|
15
|
+
# per model class basis.
|
16
16
|
#
|
17
|
-
# * :name => method to call on an instance to produce a human meaningful
|
18
|
-
# Defaults to :name.
|
19
|
-
# * :serialization => options to be passed to
|
20
|
-
# serialization of the
|
21
|
-
#
|
22
|
-
#
|
17
|
+
# * :name => method to call on an instance to produce a human meaningful
|
18
|
+
# reference for the instance. Defaults to :name.
|
19
|
+
# * :serialization => options to be passed to
|
20
|
+
# ActiveRecord::Serialization::Serializer to configure serialization of the
|
21
|
+
# ActiveRecord instance itself. See ActiveRecord::Serialization.to_json
|
22
|
+
# * :url_for => if the named_route helper method cannot be guessed from normal
|
23
|
+
# Rails restful syntax, it may be overriden here.
|
23
24
|
# * :associations => you may include href references to the instance's associations
|
24
|
-
# * :shallow => if you are serializing an association, by default member
|
25
|
-
# references are stripped. Set this to false to
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
25
|
+
# * :shallow => if you are serializing an association, by default member
|
26
|
+
# includes and association references are stripped. Set this to false to
|
27
|
+
# traverse deeply.
|
28
|
+
# * :no_inherited_options => normally a subclass inherits and overrides its
|
29
|
+
# base class settings. Setting this to true prevents this so that only the
|
30
|
+
# options specifically set for the class will be used. Default false.
|
29
31
|
#
|
30
32
|
# = Usage
|
31
33
|
#
|
@@ -56,7 +58,7 @@ require 'restful/serializer'
|
|
56
58
|
#
|
57
59
|
# Restful.model_configuration = {
|
58
60
|
# :person => {
|
59
|
-
# :serialization => { :except => :secrets }
|
61
|
+
# :serialization => { :except => [:secrets] }
|
60
62
|
# :associations => :books,
|
61
63
|
# }
|
62
64
|
# :book => {
|
@@ -74,10 +76,48 @@ require 'restful/serializer'
|
|
74
76
|
# # 'first_name' => 'Bob',
|
75
77
|
# # 'last_name' => 'Bob',
|
76
78
|
# # 'age' : 17,
|
79
|
+
# # },
|
77
80
|
# # 'href' => 'http://www.example.com/web_service/people/1' }
|
78
81
|
# # 'books_href' => 'http://www.example.com/web_service/people/1/books' }
|
79
82
|
# # }
|
80
83
|
#
|
84
|
+
# Options may be overridden at call time, by default this overwrite the passed options completely:
|
85
|
+
#
|
86
|
+
# bob = Person.new(:first_name => 'Bob', :last_name => 'Smith', :age => 41, :secrets => 'untold')
|
87
|
+
# bob.restful(:serialization => { :except => [:id] })
|
88
|
+
# # => {
|
89
|
+
# # 'name' => 'Bob Smith'
|
90
|
+
# # 'person' => {
|
91
|
+
# # 'first_name' => 'Bob',
|
92
|
+
# # 'last_name' => 'Bob',
|
93
|
+
# # 'age' : 17,
|
94
|
+
# # 'secrets' : 'untold',
|
95
|
+
# # },
|
96
|
+
# # 'href' => 'http://www.example.com/web_service/people/1' }
|
97
|
+
# # 'books_href' => 'http://www.example.com/web_service/people/1/books' }
|
98
|
+
# # }
|
99
|
+
#
|
100
|
+
# To perform a deep merge of options instead, place the options to be deeply merged
|
101
|
+
# inside a :deep_merge hash:
|
102
|
+
#
|
103
|
+
# bob = Person.new(:first_name => 'Bob', :last_name => 'Smith', :age => 41, :secrets => 'untold')
|
104
|
+
# bob.restful(:deep_merge => { :serialization => { :except => [:id] } })
|
105
|
+
# # => {
|
106
|
+
# # 'name' => 'Bob Smith'
|
107
|
+
# # 'person' => {
|
108
|
+
# # 'first_name' => 'Bob',
|
109
|
+
# # 'last_name' => 'Bob',
|
110
|
+
# # 'age' : 17,
|
111
|
+
# # },
|
112
|
+
# # 'href' => 'http://www.example.com/web_service/people/1' }
|
113
|
+
# # 'books_href' => 'http://www.example.com/web_service/people/1/books' }
|
114
|
+
# # }
|
115
|
+
#
|
116
|
+
# These two techniques can be combined, but overwriting will occur prior to a deep merge...
|
117
|
+
#
|
118
|
+
# (There is a trap in how deep merge handles this. If the above :except values had
|
119
|
+
# not been configured as arrays, then deep merge would have overwritten rather than merging
|
120
|
+
# them. This could probably be adjusted with a closer look into the deep_merge docs.)
|
81
121
|
module Restful
|
82
122
|
# Route prefix for api calls.
|
83
123
|
mattr_accessor :api_prefix
|
data/lib/restful/serializer.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
# This file is part of restful_serializer. Copyright 2011 Joshua Partlow. This is free software, see the LICENSE file for details.
|
2
2
|
require 'active_record'
|
3
3
|
require 'action_controller'
|
4
|
+
require 'deep_merge'
|
4
5
|
|
5
6
|
module Restful
|
6
7
|
module UrlForHelpers
|
7
8
|
|
8
|
-
# Used to construct and attempt to call named routes be providing resource
|
9
|
-
# of which
|
9
|
+
# Used to construct and attempt to call named routes be providing resource
|
10
|
+
# strings out of which a named route method name will be constructed:
|
10
11
|
#
|
11
12
|
# Options:
|
12
13
|
#
|
13
|
-
# * :resources => a symbol, string or array of same describing segments of
|
14
|
-
# e.g. [:user, :comments] => user_comments (to
|
14
|
+
# * :resources => a symbol, string or array of same describing segments of
|
15
|
+
# the helper method name. e.g. [:user, :comments] => user_comments (to
|
16
|
+
# which _url will be appended...)
|
15
17
|
# * :method => overrides the use of :resources and :prefix
|
16
18
|
# * :args => any arguments to be passed to the named_route when it is called
|
17
19
|
#
|
@@ -39,16 +41,23 @@ module Restful
|
|
39
41
|
def initialize(subject, *args)
|
40
42
|
self.subject = subject
|
41
43
|
|
42
|
-
self.base_klass = subject.class.base_class.name.underscore if subject.class.respond_to?(:base_class)
|
43
|
-
self.klass = subject.class.name.underscore
|
44
|
+
self.base_klass = subject.class.base_class.name.demodulize.underscore if subject.class.respond_to?(:base_class)
|
45
|
+
self.klass = subject.class.name.demodulize.underscore
|
44
46
|
|
45
47
|
passed_options = (args.pop || {}).symbolize_keys
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
if subject.kind_of?(Array)
|
49
|
+
# preserve options as is to be passed to array members
|
50
|
+
self.options = passed_options
|
51
|
+
else
|
52
|
+
deeply_merge = passed_options.delete(:deep_merge)
|
53
|
+
base_options = Restful.model_configuration_for(base_klass) || {}
|
54
|
+
class_options = Restful.model_configuration_for(klass) || {}
|
55
|
+
self.options = (klass == base_klass || class_options[:no_inherited_options]) ?
|
56
|
+
class_options :
|
57
|
+
base_options.merge(class_options)
|
58
|
+
self.options.merge!(passed_options)
|
59
|
+
self.options.deep_merge(deeply_merge) if deeply_merge
|
60
|
+
end
|
52
61
|
|
53
62
|
self.shallow = options[:shallow]
|
54
63
|
end
|
data/lib/restful/version.rb
CHANGED
data/restful_serializer.gemspec
CHANGED
@@ -27,4 +27,5 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_runtime_dependency(%q<activerecord>, [">= 2.1.0", "<3.0.0"])
|
28
28
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.1.0", "<3.0.0"])
|
29
29
|
s.add_runtime_dependency(%q<actionpack>, [">= 2.1.0", "<3.0.0"])
|
30
|
+
s.add_runtime_dependency(%q<deep_merge>, [">= 0.1.0"])
|
30
31
|
end
|
data/spec/restful_spec.rb
CHANGED
@@ -19,13 +19,13 @@ describe Restful do
|
|
19
19
|
|
20
20
|
describe "looking up model configurations" do
|
21
21
|
|
22
|
-
class
|
23
|
-
class
|
22
|
+
class Super; end
|
23
|
+
class SubClass < Super; end
|
24
24
|
|
25
25
|
before(:each) do
|
26
26
|
Restful.model_configuration = {
|
27
|
-
:
|
28
|
-
:
|
27
|
+
:super => :super_config,
|
28
|
+
:sub_class => :sub_class_config,
|
29
29
|
}
|
30
30
|
end
|
31
31
|
|
@@ -34,36 +34,36 @@ describe Restful do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should lookup entries by symbol" do
|
37
|
-
Restful.model_configuration_for(:
|
37
|
+
Restful.model_configuration_for(:super).should == :super_config
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should lookup entries from a string" do
|
41
|
-
Restful.model_configuration_for('
|
41
|
+
Restful.model_configuration_for('super').should == :super_config
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should lookup entries by Class" do
|
45
|
-
Restful.model_configuration_for(
|
46
|
-
Restful.model_configuration_for(
|
45
|
+
Restful.model_configuration_for(Super).should == :super_config
|
46
|
+
Restful.model_configuration_for(SubClass).should == :sub_class_config
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should lookup entries by instance class" do
|
50
|
-
Restful.model_configuration_for(
|
51
|
-
Restful.model_configuration_for(
|
50
|
+
Restful.model_configuration_for(Super.new).should == :super_config
|
51
|
+
Restful.model_configuration_for(SubClass.new).should == :sub_class_config
|
52
52
|
end
|
53
53
|
|
54
54
|
describe "with deep structures" do
|
55
55
|
|
56
56
|
before(:each) do
|
57
57
|
Restful.model_configuration = {
|
58
|
-
:
|
58
|
+
:super => { :setting => {:with => :nested_hash } }
|
59
59
|
}
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should provide deep clones of model_configuration elements" do
|
63
|
-
config = Restful.model_configuration_for(:
|
63
|
+
config = Restful.model_configuration_for(:super)
|
64
64
|
config[:setting][:with] = "changed"
|
65
65
|
Restful.model_configuration.should == {
|
66
|
-
:
|
66
|
+
:super => { :setting => {:with => :nested_hash } }
|
67
67
|
}
|
68
68
|
end
|
69
69
|
|
data/spec/serializer_spec.rb
CHANGED
@@ -140,6 +140,20 @@ describe Restful::Serializer do
|
|
140
140
|
}
|
141
141
|
end
|
142
142
|
|
143
|
+
it "should deeply merge overridden options" do
|
144
|
+
rs = Restful::Serializer.new(@foo,
|
145
|
+
:deep_merge => { :serialization => { :only => [:id] } }
|
146
|
+
)
|
147
|
+
rs.serialize.should == {
|
148
|
+
'name' => @foo.fancy_name,
|
149
|
+
'foo' => {
|
150
|
+
'id' => @foo.id,
|
151
|
+
'name' => @foo.name,
|
152
|
+
:a_method => @foo.a_method,
|
153
|
+
},
|
154
|
+
'href' => "http://test.org/prefix/foos/#{@foo.id}",
|
155
|
+
}
|
156
|
+
end
|
143
157
|
end
|
144
158
|
|
145
159
|
describe "with associations" do
|
@@ -183,7 +197,6 @@ describe Restful::Serializer do
|
|
183
197
|
'special_href' => "http://test.org/foos/#{@bar1.foo_id}",
|
184
198
|
}
|
185
199
|
end
|
186
|
-
|
187
200
|
end
|
188
201
|
|
189
202
|
describe "with subclasses" do
|
@@ -218,7 +231,7 @@ describe Restful::Serializer do
|
|
218
231
|
:associations => :bars,
|
219
232
|
},
|
220
233
|
:bar => {
|
221
|
-
:serialization => { :only => :name, :include => { :dingos => { :only => [ :name, :id] } } },
|
234
|
+
:serialization => { :only => [:name], :include => { :dingos => { :only => [ :name, :id] } } },
|
222
235
|
:associations => [:foo, :dingos],
|
223
236
|
},
|
224
237
|
}
|
@@ -276,6 +289,52 @@ describe Restful::Serializer do
|
|
276
289
|
},
|
277
290
|
]
|
278
291
|
end
|
292
|
+
|
293
|
+
it "should override options during initialization for each member" do
|
294
|
+
rs = Restful::Serializer.new(@foo.bars,
|
295
|
+
:serialization => { :only => :id }
|
296
|
+
)
|
297
|
+
rs.serialize.should == [
|
298
|
+
{
|
299
|
+
'name' => @bar1.name,
|
300
|
+
'href' => "http://test.org/bars/#{@bar1.id}",
|
301
|
+
'bar' => {
|
302
|
+
'id' => @bar1.id,
|
303
|
+
},
|
304
|
+
},
|
305
|
+
{
|
306
|
+
'name' => @bar2.name,
|
307
|
+
'href' => "http://test.org/bars/#{@bar2.id}",
|
308
|
+
'bar' => {
|
309
|
+
'id' => @bar2.id,
|
310
|
+
},
|
311
|
+
},
|
312
|
+
]
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should deeply merge overridden options for each member" do
|
316
|
+
rs = Restful::Serializer.new(@foo.bars,
|
317
|
+
:deep_merge => { :serialization => { :only => [:id] } }
|
318
|
+
)
|
319
|
+
rs.serialize.should == [
|
320
|
+
{
|
321
|
+
'name' => @bar1.name,
|
322
|
+
'href' => "http://test.org/bars/#{@bar1.id}",
|
323
|
+
'bar' => {
|
324
|
+
'id' => @bar1.id,
|
325
|
+
'name' => @bar1.name,
|
326
|
+
},
|
327
|
+
},
|
328
|
+
{
|
329
|
+
'name' => @bar2.name,
|
330
|
+
'href' => "http://test.org/bars/#{@bar2.id}",
|
331
|
+
'bar' => {
|
332
|
+
'id' => @bar2.id,
|
333
|
+
'name' => @bar2.name,
|
334
|
+
},
|
335
|
+
},
|
336
|
+
]
|
337
|
+
end
|
279
338
|
end
|
280
339
|
|
281
340
|
it "should hook into activerecord" do
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
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-04-
|
18
|
+
date: 2011-04-21 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -106,6 +106,22 @@ dependencies:
|
|
106
106
|
version: 3.0.0
|
107
107
|
type: :runtime
|
108
108
|
version_requirements: *id004
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: deep_merge
|
111
|
+
prerelease: false
|
112
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
hash: 27
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
- 1
|
121
|
+
- 0
|
122
|
+
version: 0.1.0
|
123
|
+
type: :runtime
|
124
|
+
version_requirements: *id005
|
109
125
|
description: This library is used to decorate ActiveRecord with methods to assist in generating Restful content for Web Services.
|
110
126
|
email: jpartlow@glatisant.org
|
111
127
|
executables: []
|
@@ -162,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
178
|
requirements: []
|
163
179
|
|
164
180
|
rubyforge_project:
|
165
|
-
rubygems_version: 1.
|
181
|
+
rubygems_version: 1.3.7
|
166
182
|
signing_key:
|
167
183
|
specification_version: 3
|
168
184
|
summary: Helps with serializing activerecord instances as Restful resources.
|