mongo_mapper_ign 0.7.7 → 0.7.8
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -20
- data/README.rdoc +34 -34
- data/bin/mmconsole +60 -60
- data/lib/mongo_mapper.rb +123 -123
- data/lib/mongo_mapper/document.rb +292 -292
- data/lib/mongo_mapper/embedded_document.rb +71 -71
- data/lib/mongo_mapper/plugins.rb +36 -36
- data/lib/mongo_mapper/plugins/associations.rb +115 -115
- data/lib/mongo_mapper/plugins/associations/base.rb +124 -124
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +31 -31
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +26 -26
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -21
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +39 -39
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +160 -144
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +29 -29
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +130 -130
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -32
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -24
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -14
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +42 -42
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +70 -70
- data/lib/mongo_mapper/plugins/associations/proxy.rb +125 -125
- data/lib/mongo_mapper/plugins/callbacks.rb +241 -241
- data/lib/mongo_mapper/plugins/clone.rb +13 -13
- data/lib/mongo_mapper/plugins/descendants.rb +16 -16
- data/lib/mongo_mapper/plugins/dirty.rb +119 -119
- data/lib/mongo_mapper/plugins/equality.rb +23 -23
- data/lib/mongo_mapper/plugins/identity_map.rb +123 -123
- data/lib/mongo_mapper/plugins/inspect.rb +14 -14
- data/lib/mongo_mapper/plugins/keys.rb +322 -322
- data/lib/mongo_mapper/plugins/keys/key.rb +53 -53
- data/lib/mongo_mapper/plugins/logger.rb +17 -17
- data/lib/mongo_mapper/plugins/modifiers.rb +111 -111
- data/lib/mongo_mapper/plugins/pagination.rb +24 -24
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +72 -72
- data/lib/mongo_mapper/plugins/persistence.rb +96 -96
- data/lib/mongo_mapper/plugins/protected.rb +46 -46
- data/lib/mongo_mapper/plugins/rails.rb +57 -57
- data/lib/mongo_mapper/plugins/serialization.rb +92 -92
- data/lib/mongo_mapper/plugins/serialization/array.rb +56 -56
- data/lib/mongo_mapper/plugins/serialization/xml_serializer.rb +239 -239
- data/lib/mongo_mapper/plugins/timestamps.rb +21 -21
- data/lib/mongo_mapper/plugins/userstamps.rb +14 -14
- data/lib/mongo_mapper/plugins/validations.rb +46 -46
- data/lib/mongo_mapper/query.rb +28 -28
- data/lib/mongo_mapper/support.rb +197 -197
- data/lib/mongo_mapper/support/descendant_appends.rb +46 -46
- data/lib/mongo_mapper/support/find.rb +77 -77
- data/lib/mongo_mapper/version.rb +3 -3
- metadata +4 -25
@@ -1,56 +1,56 @@
|
|
1
|
-
# Credit: http://github.com/tsxn26/array-xml_serialization
|
2
|
-
|
3
|
-
# Extends the XML serialization support in activesupport to allow for
|
4
|
-
# arrays containing strings, symbols, and integers.
|
5
|
-
|
6
|
-
# Forces elements in arrays to be output using to_xml on each element if the
|
7
|
-
# element responds to to_xml. If an element does not respond to to_xml then a
|
8
|
-
# nested XML tag is created with the element's to_s value and the singlarized name
|
9
|
-
# of the array as the tag name.
|
10
|
-
|
11
|
-
require 'rubygems'
|
12
|
-
require 'activesupport'
|
13
|
-
require 'builder'
|
14
|
-
|
15
|
-
class Array
|
16
|
-
def to_xml(options = {})
|
17
|
-
#raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
|
18
|
-
require 'builder' unless defined?(Builder)
|
19
|
-
|
20
|
-
options = options.dup
|
21
|
-
options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
|
22
|
-
options[:children] ||= options[:root].singularize
|
23
|
-
options[:indent] ||= 2
|
24
|
-
options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
25
|
-
|
26
|
-
root = options.delete(:root).to_s
|
27
|
-
children = options.delete(:children)
|
28
|
-
|
29
|
-
if !options.has_key?(:dasherize) || options[:dasherize]
|
30
|
-
root = root.dasherize
|
31
|
-
end
|
32
|
-
|
33
|
-
options[:builder].instruct! unless options.delete(:skip_instruct)
|
34
|
-
|
35
|
-
opts = options.merge({ :root => children })
|
36
|
-
|
37
|
-
root = root.pluralize
|
38
|
-
|
39
|
-
xml = options[:builder]
|
40
|
-
if empty?
|
41
|
-
xml.tag!(root, options[:skip_types] ? {} : {:type => "array"})
|
42
|
-
else
|
43
|
-
xml.tag!(root, options[:skip_types] ? {} : {:type => "array"}) do
|
44
|
-
yield xml if block_given?
|
45
|
-
each do |e|
|
46
|
-
if e.respond_to? :to_xml
|
47
|
-
e.to_xml(opts.merge({ :skip_instruct => true }))
|
48
|
-
else
|
49
|
-
xml.tag!(root.singularize, e.to_s)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
1
|
+
# Credit: http://github.com/tsxn26/array-xml_serialization
|
2
|
+
|
3
|
+
# Extends the XML serialization support in activesupport to allow for
|
4
|
+
# arrays containing strings, symbols, and integers.
|
5
|
+
|
6
|
+
# Forces elements in arrays to be output using to_xml on each element if the
|
7
|
+
# element responds to to_xml. If an element does not respond to to_xml then a
|
8
|
+
# nested XML tag is created with the element's to_s value and the singlarized name
|
9
|
+
# of the array as the tag name.
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'activesupport'
|
13
|
+
require 'builder'
|
14
|
+
|
15
|
+
class Array
|
16
|
+
def to_xml(options = {})
|
17
|
+
#raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
|
18
|
+
require 'builder' unless defined?(Builder)
|
19
|
+
|
20
|
+
options = options.dup
|
21
|
+
options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
|
22
|
+
options[:children] ||= options[:root].singularize
|
23
|
+
options[:indent] ||= 2
|
24
|
+
options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
25
|
+
|
26
|
+
root = options.delete(:root).to_s
|
27
|
+
children = options.delete(:children)
|
28
|
+
|
29
|
+
if !options.has_key?(:dasherize) || options[:dasherize]
|
30
|
+
root = root.dasherize
|
31
|
+
end
|
32
|
+
|
33
|
+
options[:builder].instruct! unless options.delete(:skip_instruct)
|
34
|
+
|
35
|
+
opts = options.merge({ :root => children })
|
36
|
+
|
37
|
+
root = root.pluralize
|
38
|
+
|
39
|
+
xml = options[:builder]
|
40
|
+
if empty?
|
41
|
+
xml.tag!(root, options[:skip_types] ? {} : {:type => "array"})
|
42
|
+
else
|
43
|
+
xml.tag!(root, options[:skip_types] ? {} : {:type => "array"}) do
|
44
|
+
yield xml if block_given?
|
45
|
+
each do |e|
|
46
|
+
if e.respond_to? :to_xml
|
47
|
+
e.to_xml(opts.merge({ :skip_instruct => true }))
|
48
|
+
else
|
49
|
+
xml.tag!(root.singularize, e.to_s)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -1,240 +1,240 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Serialization
|
4
|
-
|
5
|
-
class XmlSerializer #:nodoc:
|
6
|
-
attr_reader :options
|
7
|
-
|
8
|
-
def initialize(record, options = {})
|
9
|
-
@record, @options = record, options.dup
|
10
|
-
end
|
11
|
-
|
12
|
-
def builder
|
13
|
-
@builder ||= begin
|
14
|
-
options[:indent] ||= 2
|
15
|
-
builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
16
|
-
|
17
|
-
unless options[:skip_instruct]
|
18
|
-
builder.instruct!
|
19
|
-
options[:skip_instruct] = true
|
20
|
-
end
|
21
|
-
|
22
|
-
builder
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def root
|
27
|
-
root = (options[:root] || @record.class.to_s.underscore).to_s
|
28
|
-
dasherize? ? root.dasherize : root
|
29
|
-
end
|
30
|
-
|
31
|
-
def dasherize?
|
32
|
-
!options.has_key?(:dasherize) || options[:dasherize]
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
# To replicate the behavior in ActiveRecord#attributes,
|
37
|
-
# :except takes precedence over :only. If :only is not set
|
38
|
-
# for a N level model but is set for the N+1 level models,
|
39
|
-
# then because :except is set to a default value, the second
|
40
|
-
# level model can have both :except and :only set. So if
|
41
|
-
# :only is set, always delete :except.
|
42
|
-
def serializable_attributes
|
43
|
-
#attribute_names = @record.attributes.keys # This includes all attributes including associations
|
44
|
-
attribute_names = @record.class.keys.keys # This includes just keys
|
45
|
-
idex = attribute_names.index("_id")
|
46
|
-
attribute_names[idex] = "id" if idex
|
47
|
-
|
48
|
-
if options[:only]
|
49
|
-
options.delete(:except)
|
50
|
-
attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
|
51
|
-
else
|
52
|
-
options[:except] = Array(options[:except])
|
53
|
-
attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
|
54
|
-
end
|
55
|
-
|
56
|
-
attribute_names.collect { |name| Attribute.new(name, @record) }
|
57
|
-
end
|
58
|
-
|
59
|
-
def serializable_method_attributes
|
60
|
-
Array(options[:methods]).collect { |name| MethodAttribute.new(name.to_s, @record) }
|
61
|
-
end
|
62
|
-
|
63
|
-
def add_attributes
|
64
|
-
(serializable_attributes + serializable_method_attributes).each do |attribute|
|
65
|
-
add_tag(attribute)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def add_includes
|
70
|
-
if include_associations = options.delete(:include)
|
71
|
-
root_only_or_except = { :except => options[:except],
|
72
|
-
:only => options[:only] }
|
73
|
-
|
74
|
-
include_has_options = include_associations.is_a?(Hash)
|
75
|
-
|
76
|
-
for association in include_has_options ? include_associations.keys : Array(include_associations)
|
77
|
-
association_options = include_has_options ? include_associations[association] : root_only_or_except
|
78
|
-
|
79
|
-
opts = options.merge(association_options)
|
80
|
-
|
81
|
-
case @record.class.associations[association].type
|
82
|
-
when :many, :has_and_belongs_to_many
|
83
|
-
records = @record.send(association).to_a
|
84
|
-
unless records.empty?
|
85
|
-
tag = association.to_s
|
86
|
-
tag = tag.dasherize if dasherize?
|
87
|
-
|
88
|
-
builder.tag!(tag) do
|
89
|
-
records.each { |r| r.to_xml(opts.merge(:root=>r.class.to_s.underscore)) }
|
90
|
-
end
|
91
|
-
end
|
92
|
-
when :has_one, :belongs_to
|
93
|
-
if record = @record.send(association)
|
94
|
-
record.to_xml(opts.merge(:root => association))
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
options[:include] = include_associations
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def add_procs
|
104
|
-
if procs = options.delete(:procs)
|
105
|
-
[ *procs ].each do |proc|
|
106
|
-
proc.call(options)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
def add_tag(attribute)
|
113
|
-
if attribute.type == :array
|
114
|
-
builder.tag!(
|
115
|
-
dasherize? ? attribute.name.dasherize.pluralize : attribute.name.pluralize,
|
116
|
-
attribute.decorations(!options[:skip_types])
|
117
|
-
) do |x|
|
118
|
-
attribute.value.each do |val|
|
119
|
-
if val.respond_to? :to_xml
|
120
|
-
x << val.to_xml(:skip_instruct => true, :root => attribute.name.dasherize.singularize)
|
121
|
-
else
|
122
|
-
x.tag!(
|
123
|
-
dasherize? ? attribute.name.dasherize.singularize : attribute.name.singularize,
|
124
|
-
val.to_s
|
125
|
-
)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
else
|
130
|
-
builder.tag!(
|
131
|
-
dasherize? ? attribute.name.dasherize : attribute.name,
|
132
|
-
attribute.value.to_s,
|
133
|
-
attribute.decorations(!options[:skip_types])
|
134
|
-
)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def serialize
|
139
|
-
args = [root]
|
140
|
-
if options[:namespace]
|
141
|
-
args << {:xmlns=>options[:namespace]}
|
142
|
-
end
|
143
|
-
|
144
|
-
builder.tag!(*args) do
|
145
|
-
add_attributes
|
146
|
-
add_includes
|
147
|
-
add_procs
|
148
|
-
yield builder if block_given?
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
alias_method :to_s, :serialize
|
153
|
-
|
154
|
-
class Attribute #:nodoc:
|
155
|
-
attr_reader :name, :value, :type
|
156
|
-
|
157
|
-
def initialize(name, record)
|
158
|
-
@name, @record = name, record
|
159
|
-
|
160
|
-
@type = compute_type
|
161
|
-
@value = compute_value
|
162
|
-
end
|
163
|
-
|
164
|
-
# There is a significant speed improvement if the value
|
165
|
-
# does not need to be escaped, as #tag! escapes all values
|
166
|
-
# to ensure that valid XML is generated. For known binary
|
167
|
-
# values, it is at least an order of magnitude faster to
|
168
|
-
# Base64 encode binary values and directly put them in the
|
169
|
-
# output XML than to pass the original value or the Base64
|
170
|
-
# encoded value to the #tag! method. It definitely makes
|
171
|
-
# no sense to Base64 encode the value and then give it to
|
172
|
-
# #tag!, since that just adds additional overhead.
|
173
|
-
def needs_encoding?
|
174
|
-
![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
|
175
|
-
end
|
176
|
-
|
177
|
-
def decorations(include_types = true)
|
178
|
-
decorations = {}
|
179
|
-
|
180
|
-
if type == :binary
|
181
|
-
decorations[:encoding] = 'base64'
|
182
|
-
end
|
183
|
-
|
184
|
-
if include_types && type != :string
|
185
|
-
decorations[:type] = type
|
186
|
-
end
|
187
|
-
|
188
|
-
decorations
|
189
|
-
end
|
190
|
-
|
191
|
-
protected
|
192
|
-
def compute_type
|
193
|
-
if name == "id"
|
194
|
-
return :object_id
|
195
|
-
end
|
196
|
-
|
197
|
-
#type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type
|
198
|
-
v = @record.class.keys[name]
|
199
|
-
#puts "Value type is........... #{v.type.to_s} #{v.type.to_s.blank?}"
|
200
|
-
|
201
|
-
#type = @record.send(name).class
|
202
|
-
|
203
|
-
type = v.nil? ? :yaml : (v.type.to_s.blank? ? :key : v.type.to_s.underscore.to_sym)
|
204
|
-
|
205
|
-
case type
|
206
|
-
when :text
|
207
|
-
:string
|
208
|
-
when :time
|
209
|
-
:datetime
|
210
|
-
# when :array
|
211
|
-
# :yaml
|
212
|
-
else
|
213
|
-
type
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def compute_value
|
218
|
-
n = name == "id" ? "_id" : name
|
219
|
-
|
220
|
-
value = @record.send(n)
|
221
|
-
|
222
|
-
if formatter = Hash::XML_FORMATTING[type.to_s]
|
223
|
-
value ? formatter.call(value) : nil
|
224
|
-
else
|
225
|
-
value
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
class MethodAttribute < Attribute #:nodoc:
|
231
|
-
protected
|
232
|
-
def compute_type
|
233
|
-
Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
end
|
239
|
-
end
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module Serialization
|
4
|
+
|
5
|
+
class XmlSerializer #:nodoc:
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(record, options = {})
|
9
|
+
@record, @options = record, options.dup
|
10
|
+
end
|
11
|
+
|
12
|
+
def builder
|
13
|
+
@builder ||= begin
|
14
|
+
options[:indent] ||= 2
|
15
|
+
builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
16
|
+
|
17
|
+
unless options[:skip_instruct]
|
18
|
+
builder.instruct!
|
19
|
+
options[:skip_instruct] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
builder
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def root
|
27
|
+
root = (options[:root] || @record.class.to_s.underscore).to_s
|
28
|
+
dasherize? ? root.dasherize : root
|
29
|
+
end
|
30
|
+
|
31
|
+
def dasherize?
|
32
|
+
!options.has_key?(:dasherize) || options[:dasherize]
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# To replicate the behavior in ActiveRecord#attributes,
|
37
|
+
# :except takes precedence over :only. If :only is not set
|
38
|
+
# for a N level model but is set for the N+1 level models,
|
39
|
+
# then because :except is set to a default value, the second
|
40
|
+
# level model can have both :except and :only set. So if
|
41
|
+
# :only is set, always delete :except.
|
42
|
+
def serializable_attributes
|
43
|
+
#attribute_names = @record.attributes.keys # This includes all attributes including associations
|
44
|
+
attribute_names = @record.class.keys.keys # This includes just keys
|
45
|
+
idex = attribute_names.index("_id")
|
46
|
+
attribute_names[idex] = "id" if idex
|
47
|
+
|
48
|
+
if options[:only]
|
49
|
+
options.delete(:except)
|
50
|
+
attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
|
51
|
+
else
|
52
|
+
options[:except] = Array(options[:except])
|
53
|
+
attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
|
54
|
+
end
|
55
|
+
|
56
|
+
attribute_names.collect { |name| Attribute.new(name, @record) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def serializable_method_attributes
|
60
|
+
Array(options[:methods]).collect { |name| MethodAttribute.new(name.to_s, @record) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_attributes
|
64
|
+
(serializable_attributes + serializable_method_attributes).each do |attribute|
|
65
|
+
add_tag(attribute)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_includes
|
70
|
+
if include_associations = options.delete(:include)
|
71
|
+
root_only_or_except = { :except => options[:except],
|
72
|
+
:only => options[:only] }
|
73
|
+
|
74
|
+
include_has_options = include_associations.is_a?(Hash)
|
75
|
+
|
76
|
+
for association in include_has_options ? include_associations.keys : Array(include_associations)
|
77
|
+
association_options = include_has_options ? include_associations[association] : root_only_or_except
|
78
|
+
|
79
|
+
opts = options.merge(association_options)
|
80
|
+
|
81
|
+
case @record.class.associations[association].type
|
82
|
+
when :many, :has_and_belongs_to_many
|
83
|
+
records = @record.send(association).to_a
|
84
|
+
unless records.empty?
|
85
|
+
tag = association.to_s
|
86
|
+
tag = tag.dasherize if dasherize?
|
87
|
+
|
88
|
+
builder.tag!(tag) do
|
89
|
+
records.each { |r| r.to_xml(opts.merge(:root=>r.class.to_s.underscore)) }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
when :has_one, :belongs_to
|
93
|
+
if record = @record.send(association)
|
94
|
+
record.to_xml(opts.merge(:root => association))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
options[:include] = include_associations
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_procs
|
104
|
+
if procs = options.delete(:procs)
|
105
|
+
[ *procs ].each do |proc|
|
106
|
+
proc.call(options)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
def add_tag(attribute)
|
113
|
+
if attribute.type == :array
|
114
|
+
builder.tag!(
|
115
|
+
dasherize? ? attribute.name.dasherize.pluralize : attribute.name.pluralize,
|
116
|
+
attribute.decorations(!options[:skip_types])
|
117
|
+
) do |x|
|
118
|
+
attribute.value.each do |val|
|
119
|
+
if val.respond_to? :to_xml
|
120
|
+
x << val.to_xml(:skip_instruct => true, :root => attribute.name.dasherize.singularize)
|
121
|
+
else
|
122
|
+
x.tag!(
|
123
|
+
dasherize? ? attribute.name.dasherize.singularize : attribute.name.singularize,
|
124
|
+
val.to_s
|
125
|
+
)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
builder.tag!(
|
131
|
+
dasherize? ? attribute.name.dasherize : attribute.name,
|
132
|
+
attribute.value.to_s,
|
133
|
+
attribute.decorations(!options[:skip_types])
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def serialize
|
139
|
+
args = [root]
|
140
|
+
if options[:namespace]
|
141
|
+
args << {:xmlns=>options[:namespace]}
|
142
|
+
end
|
143
|
+
|
144
|
+
builder.tag!(*args) do
|
145
|
+
add_attributes
|
146
|
+
add_includes
|
147
|
+
add_procs
|
148
|
+
yield builder if block_given?
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
alias_method :to_s, :serialize
|
153
|
+
|
154
|
+
class Attribute #:nodoc:
|
155
|
+
attr_reader :name, :value, :type
|
156
|
+
|
157
|
+
def initialize(name, record)
|
158
|
+
@name, @record = name, record
|
159
|
+
|
160
|
+
@type = compute_type
|
161
|
+
@value = compute_value
|
162
|
+
end
|
163
|
+
|
164
|
+
# There is a significant speed improvement if the value
|
165
|
+
# does not need to be escaped, as #tag! escapes all values
|
166
|
+
# to ensure that valid XML is generated. For known binary
|
167
|
+
# values, it is at least an order of magnitude faster to
|
168
|
+
# Base64 encode binary values and directly put them in the
|
169
|
+
# output XML than to pass the original value or the Base64
|
170
|
+
# encoded value to the #tag! method. It definitely makes
|
171
|
+
# no sense to Base64 encode the value and then give it to
|
172
|
+
# #tag!, since that just adds additional overhead.
|
173
|
+
def needs_encoding?
|
174
|
+
![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
|
175
|
+
end
|
176
|
+
|
177
|
+
def decorations(include_types = true)
|
178
|
+
decorations = {}
|
179
|
+
|
180
|
+
if type == :binary
|
181
|
+
decorations[:encoding] = 'base64'
|
182
|
+
end
|
183
|
+
|
184
|
+
if include_types && type != :string
|
185
|
+
decorations[:type] = type
|
186
|
+
end
|
187
|
+
|
188
|
+
decorations
|
189
|
+
end
|
190
|
+
|
191
|
+
protected
|
192
|
+
def compute_type
|
193
|
+
if name == "id"
|
194
|
+
return :object_id
|
195
|
+
end
|
196
|
+
|
197
|
+
#type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type
|
198
|
+
v = @record.class.keys[name]
|
199
|
+
#puts "Value type is........... #{v.type.to_s} #{v.type.to_s.blank?}"
|
200
|
+
|
201
|
+
#type = @record.send(name).class
|
202
|
+
|
203
|
+
type = v.nil? ? :yaml : (v.type.to_s.blank? ? :key : v.type.to_s.underscore.to_sym)
|
204
|
+
|
205
|
+
case type
|
206
|
+
when :text
|
207
|
+
:string
|
208
|
+
when :time
|
209
|
+
:datetime
|
210
|
+
# when :array
|
211
|
+
# :yaml
|
212
|
+
else
|
213
|
+
type
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def compute_value
|
218
|
+
n = name == "id" ? "_id" : name
|
219
|
+
|
220
|
+
value = @record.send(n)
|
221
|
+
|
222
|
+
if formatter = Hash::XML_FORMATTING[type.to_s]
|
223
|
+
value ? formatter.call(value) : nil
|
224
|
+
else
|
225
|
+
value
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class MethodAttribute < Attribute #:nodoc:
|
231
|
+
protected
|
232
|
+
def compute_type
|
233
|
+
Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
end
|
240
240
|
end
|