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 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 = {}
@@ -3,27 +3,55 @@ require 'deep_merge'
3
3
 
4
4
  module Restful
5
5
 
6
- module UrlForHelpers
7
-
8
- # Used to construct and attempt to call named routes by providing resource
9
- # strings out of which a named route method name will be constructed:
10
- #
11
- # Options:
12
- #
13
- # * :resources => a symbol, string or array of same describing segments of
14
- # the helper method name. e.g. [:user, :comments] => user_comments (to
15
- # which _url will be appended...)
16
- # * :method => overrides the use of :resources and :prefix
17
- # * :args => any arguments to be passed to the named_route when it is called
18
- #
19
- # = Example
20
- #
21
- # get_url_for(:resources => [:user, :comments], :args => 1)
22
- # # => send("#{Restful.api_prefix}_user_comments_url", 1)
23
- # # which if it exists is likely to return something like:
24
- # # "http://example.com/user/1/comments"
25
- #
26
- def get_url_for(options)
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
- class Serializer
36
- include ActionController::UrlWriter
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
- alias_method :serializer_default_url_options=, :default_url_options=
43
- # Set ActionController::UrlWriter.default_url_options for all Serializer
44
- # actions.
45
- def default_url_options=(options)
46
- self.serializer_default_url_options = options
47
- Association.default_url_options = options
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 = get_url_for(:method => options[:url_for], :args => subject.id) if options.include?(:url_for)
113
- @href = get_url_for(:resources => klass, :args => subject.id) unless @href
114
- @href = get_url_for(:resources => base_klass, :args => subject.id) unless @href || base_klass == klass
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 = get_url_for(:resources => association_name, :args => subject.send(association.name).id)
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 = get_url_for(:resources => [subject_klass, association_name], :args => subject.id)
174
- href = get_url_for(:resources => association_name)
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
@@ -1,3 +1,3 @@
1
1
  module Restful
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
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
@@ -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::Serializer.default_url_options = { :host => 'test.org' }
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
- :a_method => @foo.a_method,
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
- :a_method => @foo.a_method,
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
- :dingos => [
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
- :dingos => [
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: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
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-12 00:00:00 -07:00
18
+ date: 2011-05-19 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency