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 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