activemodel-serializers-xml 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6bc425067f4464c88dee88509467b43023e6403f
4
+ data.tar.gz: be43d228780d3b5d1fc36e601a6683843dfde5a9
5
+ SHA512:
6
+ metadata.gz: 94f24ac26395ceee9a15e4b3587acdbb4f43b5d6485b7721dd4d3f111dbdc3c65dc8ae77faa931fb8383eb224082f9870b6f72c6d0bee40b10ce21eafe5e0066
7
+ data.tar.gz: 7a8b5bf946628353d49a7c746a94cc689d2eaf747a1e73fd3609e97f47e181feedece4e58bc27c4f67f77013480ffce00c21499ed2e37f0838236ede3cfef104
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ sudo: false
3
+ script:
4
+ - bundle exec rake test
5
+ rvm:
6
+ - 2.2 # tests on latest 2.2.x
7
+ - ruby-head
8
+ - rbx-2
9
+ - jruby-head
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: rbx-2
14
+ - rvm: jruby-head
15
+ fast_finish: true
@@ -0,0 +1,99 @@
1
+ Contributing to ActiveModel::Serializers::Xml
2
+ =====================
3
+
4
+ [![Build Status](https://api.travis-ci.org/rails/activemodel-serializers-xml.svg)](https://travis-ci.org/rails/activemodel-serializers-xml)
5
+
6
+ ActiveModel::Serializers::Xml is work of [many contributors](https://github.com/rails/activemodel-serializers-xml/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/rails/activemodel-serializers-xml/pulls), [propose features and discuss issues](https://github.com/rails/activemodel-serializers-xml/issues).
7
+
8
+ #### Fork the Project
9
+
10
+ Fork the [project on Github](https://github.com/rails/activemodel-serializers-xml) and check out your copy.
11
+
12
+ ```
13
+ git clone https://github.com/contributor/activemodel-serializers-xml.git
14
+ cd activemodel-serializers-xml
15
+ git remote add upstream https://github.com/rails/activemodel-serializers-xml.git
16
+ ```
17
+
18
+ #### Create a Topic Branch
19
+
20
+ Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
21
+
22
+ ```
23
+ git checkout master
24
+ git pull upstream master
25
+ git checkout -b my-feature-branch
26
+ ```
27
+
28
+ #### Bundle Install and Test
29
+
30
+ Ensure that you can build the project and run tests.
31
+
32
+ ```
33
+ bundle install
34
+ bundle exec rake test
35
+ ```
36
+
37
+ #### Write Tests
38
+
39
+ Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [test](test).
40
+
41
+ We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix.
42
+
43
+ #### Write Code
44
+
45
+ Implement your feature or bug fix.
46
+
47
+ Make sure that `bundle exec rake test` completes without errors.
48
+
49
+ #### Write Documentation
50
+
51
+ Document any external behavior in the [README](README.md).
52
+
53
+ #### Commit Changes
54
+
55
+ Make sure git knows your name and email address:
56
+
57
+ ```
58
+ git config --global user.name "Your Name"
59
+ git config --global user.email "contributor@example.com"
60
+ ```
61
+
62
+ Writing good commit logs is important. A commit log should describe what changed and why.
63
+
64
+ ```
65
+ git add ...
66
+ git commit
67
+ ```
68
+
69
+ #### Push
70
+
71
+ ```
72
+ git push origin my-feature-branch
73
+ ```
74
+
75
+ #### Make a Pull Request
76
+
77
+ Go to https://github.com/contributor/activemodel-serializers-xml and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
78
+
79
+ #### Rebase
80
+
81
+ If you've been working on a change for a while, rebase with upstream/master.
82
+
83
+ ```
84
+ git fetch upstream
85
+ git rebase upstream/master
86
+ git push origin my-feature-branch -f
87
+ ```
88
+
89
+ #### Check on Your Pull Request
90
+
91
+ Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above.
92
+
93
+ #### Be Patient
94
+
95
+ It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there!
96
+
97
+ #### Thank You
98
+
99
+ Please do know that we really appreciate and value your time and work. We love you, really.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activemodel-serializers-xml.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Zachary Scott
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,89 @@
1
+ # ActiveModel::Serializers::Xml
2
+
3
+ This gem provides XML serialization for your Active Model objects and Active Record models.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'activemodel-serializers-xml'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install activemodel-serializers-xml
20
+
21
+ ## Usage
22
+
23
+ ### ActiveModel::Serializers::Xml
24
+
25
+ To use the `ActiveModel::Serializers::Xml` you only need to change from
26
+ `ActiveModel::Serialization` to `ActiveModel::Serializers::Xml`.
27
+
28
+ ```ruby
29
+ class Person
30
+ include ActiveModel::Serializers::Xml
31
+
32
+ attr_accessor :name
33
+
34
+ def attributes
35
+ {'name' => nil}
36
+ end
37
+ end
38
+ ```
39
+
40
+ With the `to_xml` you have an XML representing the model.
41
+
42
+ ```ruby
43
+ person = Person.new
44
+ person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<person>\n <name nil=\"true\"/>\n</person>\n"
45
+ person.name = "Bob"
46
+ person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<person>\n <name>Bob</name>\n</person>\n"
47
+ ```
48
+
49
+ From an XML string you define the attributes of the model.
50
+ You need to have the `attributes=` method defined on your class:
51
+
52
+ ```ruby
53
+ class Person
54
+ include ActiveModel::Serializers::Xml
55
+
56
+ attr_accessor :name
57
+
58
+ def attributes=(hash)
59
+ hash.each do |key, value|
60
+ send("#{key}=", value)
61
+ end
62
+ end
63
+
64
+ def attributes
65
+ {'name' => nil}
66
+ end
67
+ end
68
+ ```
69
+
70
+ Now it is possible to create an instance of person and set the attributes using `from_xml`.
71
+
72
+ ```ruby
73
+ xml = { name: 'Bob' }.to_xml
74
+ person = Person.new
75
+ person.from_xml(xml) # => #<Person:0x00000100c773f0 @name="Bob">
76
+ person.name # => "Bob"
77
+ ```
78
+
79
+ ### ActiveRecord::XmlSerializer
80
+
81
+ This gem also provides serialization to XML for Active Record.
82
+
83
+ Please see ActiveRecord::Serialization#to_xml for more information.
84
+
85
+ ## Contributing to ActiveModel::Serializers::Xml
86
+
87
+ ActiveModel::Serializers::Xml is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues.
88
+
89
+ See [CONTRIBUTING](CONTRIBUTING.md)
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/**/*_test.rb']
7
+ t.verbose = true
8
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_model/serializers/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "activemodel-serializers-xml"
8
+ spec.version = ActiveModel::Serializers::VERSION
9
+ spec.authors = ["Zachary Scott"]
10
+ spec.email = ["e@zzak.io"]
11
+
12
+ spec.summary = "XML serialization for your Active Model objects and Active Record models - extracted from Rails"
13
+ spec.homepage = "http://github.com/rails/activemodel-serializers-xml"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ["lib"]
18
+ spec.add_dependency "activesupport", "> 5.x"
19
+ spec.add_dependency "activemodel", "> 5.x"
20
+ spec.add_dependency "activerecord", "> 5.x"
21
+ spec.add_dependency "builder", "~> 3.1"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.9"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "sqlite3"
26
+ end
@@ -0,0 +1 @@
1
+ require 'active_model/serializers'
@@ -0,0 +1,28 @@
1
+ require 'active_support'
2
+ require 'active_support/lazy_load_hooks'
3
+ require 'active_record'
4
+ require 'active_model'
5
+ require "active_model/serializers/version"
6
+
7
+ ActiveSupport.on_load(:active_model) do
8
+ require "active_model/serializers/xml"
9
+ end
10
+
11
+ ActiveSupport.on_load(:active_record) do
12
+ require "active_record/serializers/xml_serializer"
13
+ end
14
+
15
+ module ActiveModel
16
+ module Serializers
17
+ extend ActiveSupport::Autoload
18
+
19
+ eager_autoload do
20
+ autoload :Xml
21
+ end
22
+ end
23
+
24
+ def self.eager_load!
25
+ super
26
+ ActiveModel::Serializers.eager_load!
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveModel
2
+ module Serializers
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,238 @@
1
+ require 'active_support/deprecation'
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
+ require 'active_support/core_ext/array/conversions'
4
+ require 'active_support/core_ext/hash/conversions'
5
+ require 'active_support/core_ext/hash/slice'
6
+ require 'active_support/core_ext/time/acts_like'
7
+
8
+ module ActiveModel
9
+ module Serializers
10
+ module Xml
11
+ extend ActiveSupport::Concern
12
+ include ActiveModel::Serialization
13
+
14
+ included do
15
+ extend ActiveModel::Naming
16
+ end
17
+
18
+ class Serializer #:nodoc:
19
+ class Attribute #:nodoc:
20
+ attr_reader :name, :value, :type
21
+
22
+ def initialize(name, serializable, value)
23
+ @name, @serializable = name, serializable
24
+
25
+ if value.acts_like?(:time) && value.respond_to?(:in_time_zone)
26
+ value = value.in_time_zone
27
+ end
28
+
29
+ @value = value
30
+ @type = compute_type
31
+ end
32
+
33
+ def decorations
34
+ decorations = {}
35
+ decorations[:encoding] = 'base64' if type == :binary
36
+ decorations[:type] = (type == :string) ? nil : type
37
+ decorations[:nil] = true if value.nil?
38
+ decorations
39
+ end
40
+
41
+ protected
42
+
43
+ def compute_type
44
+ return if value.nil?
45
+ type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name]
46
+ type ||= :string if value.respond_to?(:to_str)
47
+ type ||= :yaml
48
+ type
49
+ end
50
+ end
51
+
52
+ class MethodAttribute < Attribute #:nodoc:
53
+ end
54
+
55
+ attr_reader :options
56
+
57
+ def initialize(serializable, options = nil)
58
+ @serializable = serializable
59
+ @options = options ? options.dup : {}
60
+ end
61
+
62
+ def serializable_hash
63
+ @serializable.serializable_hash(@options.except(:include))
64
+ end
65
+
66
+ def serializable_collection
67
+ methods = Array(options[:methods]).map(&:to_s)
68
+ serializable_hash.map do |name, value|
69
+ name = name.to_s
70
+ if methods.include?(name)
71
+ self.class::MethodAttribute.new(name, @serializable, value)
72
+ else
73
+ self.class::Attribute.new(name, @serializable, value)
74
+ end
75
+ end
76
+ end
77
+
78
+ def serialize
79
+ require 'builder' unless defined? ::Builder
80
+
81
+ options[:indent] ||= 2
82
+ options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent])
83
+
84
+ @builder = options[:builder]
85
+ @builder.instruct! unless options[:skip_instruct]
86
+
87
+ root = (options[:root] || @serializable.model_name.element).to_s
88
+ root = ActiveSupport::XmlMini.rename_key(root, options)
89
+
90
+ args = [root]
91
+ args << { xmlns: options[:namespace] } if options[:namespace]
92
+ args << { type: options[:type] } if options[:type] && !options[:skip_types]
93
+
94
+ @builder.tag!(*args) do
95
+ add_attributes_and_methods
96
+ add_includes
97
+ add_extra_behavior
98
+ add_procs
99
+ yield @builder if block_given?
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def add_extra_behavior
106
+ end
107
+
108
+ def add_attributes_and_methods
109
+ serializable_collection.each do |attribute|
110
+ key = ActiveSupport::XmlMini.rename_key(attribute.name, options)
111
+ ActiveSupport::XmlMini.to_tag(key, attribute.value,
112
+ options.merge(attribute.decorations))
113
+ end
114
+ end
115
+
116
+ def add_includes
117
+ @serializable.send(:serializable_add_includes, options) do |association, records, opts|
118
+ add_associations(association, records, opts)
119
+ end
120
+ end
121
+
122
+ # TODO: This can likely be cleaned up to simple use ActiveSupport::XmlMini.to_tag as well.
123
+ def add_associations(association, records, opts)
124
+ merged_options = opts.merge(options.slice(:builder, :indent))
125
+ merged_options[:skip_instruct] = true
126
+
127
+ [:skip_types, :dasherize, :camelize].each do |key|
128
+ merged_options[key] = options[key] if merged_options[key].nil? && !options[key].nil?
129
+ end
130
+
131
+ if records.respond_to?(:to_ary)
132
+ records = records.to_ary
133
+
134
+ tag = ActiveSupport::XmlMini.rename_key(association.to_s, options)
135
+ type = options[:skip_types] ? { } : { type: "array" }
136
+ association_name = association.to_s.singularize
137
+ merged_options[:root] = association_name
138
+
139
+ if records.empty?
140
+ @builder.tag!(tag, type)
141
+ else
142
+ @builder.tag!(tag, type) do
143
+ records.each do |record|
144
+ if options[:skip_types]
145
+ record_type = {}
146
+ else
147
+ record_class = (record.class.to_s.underscore == association_name) ? nil : record.class.name
148
+ record_type = { type: record_class }
149
+ end
150
+
151
+ record.to_xml merged_options.merge(record_type)
152
+ end
153
+ end
154
+ end
155
+ else
156
+ merged_options[:root] = association.to_s
157
+
158
+ unless records.class.to_s.underscore == association.to_s
159
+ merged_options[:type] = records.class.name
160
+ end
161
+
162
+ records.to_xml merged_options
163
+ end
164
+ end
165
+
166
+ def add_procs
167
+ if procs = options.delete(:procs)
168
+ Array(procs).each do |proc|
169
+ if proc.arity == 1
170
+ proc.call(options)
171
+ else
172
+ proc.call(options, @serializable)
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ # Returns XML representing the model. Configuration can be
180
+ # passed through +options+.
181
+ #
182
+ # Without any +options+, the returned XML string will include all the
183
+ # model's attributes.
184
+ #
185
+ # user = User.find(1)
186
+ # user.to_xml
187
+ #
188
+ # <?xml version="1.0" encoding="UTF-8"?>
189
+ # <user>
190
+ # <id type="integer">1</id>
191
+ # <name>David</name>
192
+ # <age type="integer">16</age>
193
+ # <created-at type="dateTime">2011-01-30T22:29:23Z</created-at>
194
+ # </user>
195
+ #
196
+ # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the
197
+ # attributes included, and work similar to the +attributes+ method.
198
+ #
199
+ # To include the result of some method calls on the model use <tt>:methods</tt>.
200
+ #
201
+ # To include associations use <tt>:include</tt>.
202
+ #
203
+ # For further documentation, see <tt>ActiveRecord::Serialization#to_xml</tt>
204
+ def to_xml(options = {}, &block)
205
+ Serializer.new(self, options).serialize(&block)
206
+ end
207
+
208
+ # Sets the model +attributes+ from an XML string. Returns +self+.
209
+ #
210
+ # class Person
211
+ # include ActiveModel::Serializers::Xml
212
+ #
213
+ # attr_accessor :name, :age, :awesome
214
+ #
215
+ # def attributes=(hash)
216
+ # hash.each do |key, value|
217
+ # instance_variable_set("@#{key}", value)
218
+ # end
219
+ # end
220
+ #
221
+ # def attributes
222
+ # instance_values
223
+ # end
224
+ # end
225
+ #
226
+ # xml = { name: 'bob', age: 22, awesome:true }.to_xml
227
+ # person = Person.new
228
+ # person.from_xml(xml) # => #<Person:0x007fec5e3b3c40 @age=22, @awesome=true, @name="bob">
229
+ # person.name # => "bob"
230
+ # person.age # => 22
231
+ # person.awesome # => true
232
+ def from_xml(xml)
233
+ self.attributes = Hash.from_xml(xml).values.first
234
+ self
235
+ end
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,194 @@
1
+ require 'active_support/core_ext/hash/conversions'
2
+ require 'active_model/serializers/xml'
3
+
4
+ module ActiveRecord #:nodoc:
5
+ module Serialization
6
+ include ActiveModel::Serializers::Xml
7
+
8
+ # Builds an XML document to represent the model. Some configuration is
9
+ # available through +options+. However more complicated cases should
10
+ # override ActiveRecord::Base#to_xml.
11
+ #
12
+ # By default the generated XML document will include the processing
13
+ # instruction and all the object's attributes. For example:
14
+ #
15
+ # <?xml version="1.0" encoding="UTF-8"?>
16
+ # <topic>
17
+ # <title>The First Topic</title>
18
+ # <author-name>David</author-name>
19
+ # <id type="integer">1</id>
20
+ # <approved type="boolean">false</approved>
21
+ # <replies-count type="integer">0</replies-count>
22
+ # <bonus-time type="dateTime">2000-01-01T08:28:00+12:00</bonus-time>
23
+ # <written-on type="dateTime">2003-07-16T09:28:00+1200</written-on>
24
+ # <content>Have a nice day</content>
25
+ # <author-email-address>david@loudthinking.com</author-email-address>
26
+ # <parent-id></parent-id>
27
+ # <last-read type="date">2004-04-15</last-read>
28
+ # </topic>
29
+ #
30
+ # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
31
+ # <tt>:skip_instruct</tt>, <tt>:skip_types</tt>, <tt>:dasherize</tt> and <tt>:camelize</tt> .
32
+ # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
33
+ # +attributes+ method. The default is to dasherize all column names, but you
34
+ # can disable this setting <tt>:dasherize</tt> to +false+. Setting <tt>:camelize</tt>
35
+ # to +true+ will camelize all column names - this also overrides <tt>:dasherize</tt>.
36
+ # To not have the column type included in the XML output set <tt>:skip_types</tt> to +true+.
37
+ #
38
+ # For instance:
39
+ #
40
+ # topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ])
41
+ #
42
+ # <topic>
43
+ # <title>The First Topic</title>
44
+ # <author-name>David</author-name>
45
+ # <approved type="boolean">false</approved>
46
+ # <content>Have a nice day</content>
47
+ # <author-email-address>david@loudthinking.com</author-email-address>
48
+ # <parent-id></parent-id>
49
+ # <last-read type="date">2004-04-15</last-read>
50
+ # </topic>
51
+ #
52
+ # To include first level associations use <tt>:include</tt>:
53
+ #
54
+ # firm.to_xml include: [ :account, :clients ]
55
+ #
56
+ # <?xml version="1.0" encoding="UTF-8"?>
57
+ # <firm>
58
+ # <id type="integer">1</id>
59
+ # <rating type="integer">1</rating>
60
+ # <name>37signals</name>
61
+ # <clients type="array">
62
+ # <client>
63
+ # <rating type="integer">1</rating>
64
+ # <name>Summit</name>
65
+ # </client>
66
+ # <client>
67
+ # <rating type="integer">1</rating>
68
+ # <name>Microsoft</name>
69
+ # </client>
70
+ # </clients>
71
+ # <account>
72
+ # <id type="integer">1</id>
73
+ # <credit-limit type="integer">50</credit-limit>
74
+ # </account>
75
+ # </firm>
76
+ #
77
+ # Additionally, the record being serialized will be passed to a Proc's second
78
+ # parameter. This allows for ad hoc additions to the resultant document that
79
+ # incorporate the context of the record being serialized. And by leveraging the
80
+ # closure created by a Proc, to_xml can be used to add elements that normally fall
81
+ # outside of the scope of the model -- for example, generating and appending URLs
82
+ # associated with models.
83
+ #
84
+ # proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
85
+ # firm.to_xml procs: [ proc ]
86
+ #
87
+ # <firm>
88
+ # # ... normal attributes as shown above ...
89
+ # <name-reverse>slangis73</name-reverse>
90
+ # </firm>
91
+ #
92
+ # To include deeper levels of associations pass a hash like this:
93
+ #
94
+ # firm.to_xml include: {account: {}, clients: {include: :address}}
95
+ # <?xml version="1.0" encoding="UTF-8"?>
96
+ # <firm>
97
+ # <id type="integer">1</id>
98
+ # <rating type="integer">1</rating>
99
+ # <name>37signals</name>
100
+ # <clients type="array">
101
+ # <client>
102
+ # <rating type="integer">1</rating>
103
+ # <name>Summit</name>
104
+ # <address>
105
+ # ...
106
+ # </address>
107
+ # </client>
108
+ # <client>
109
+ # <rating type="integer">1</rating>
110
+ # <name>Microsoft</name>
111
+ # <address>
112
+ # ...
113
+ # </address>
114
+ # </client>
115
+ # </clients>
116
+ # <account>
117
+ # <id type="integer">1</id>
118
+ # <credit-limit type="integer">50</credit-limit>
119
+ # </account>
120
+ # </firm>
121
+ #
122
+ # To include any methods on the model being called use <tt>:methods</tt>:
123
+ #
124
+ # firm.to_xml methods: [ :calculated_earnings, :real_earnings ]
125
+ #
126
+ # <firm>
127
+ # # ... normal attributes as shown above ...
128
+ # <calculated-earnings>100000000000000000</calculated-earnings>
129
+ # <real-earnings>5</real-earnings>
130
+ # </firm>
131
+ #
132
+ # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
133
+ # modified version of the options hash that was given to +to_xml+:
134
+ #
135
+ # proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
136
+ # firm.to_xml procs: [ proc ]
137
+ #
138
+ # <firm>
139
+ # # ... normal attributes as shown above ...
140
+ # <abc>def</abc>
141
+ # </firm>
142
+ #
143
+ # Alternatively, you can yield the builder object as part of the +to_xml+ call:
144
+ #
145
+ # firm.to_xml do |xml|
146
+ # xml.creator do
147
+ # xml.first_name "David"
148
+ # xml.last_name "Heinemeier Hansson"
149
+ # end
150
+ # end
151
+ #
152
+ # <firm>
153
+ # # ... normal attributes as shown above ...
154
+ # <creator>
155
+ # <first_name>David</first_name>
156
+ # <last_name>Heinemeier Hansson</last_name>
157
+ # </creator>
158
+ # </firm>
159
+ #
160
+ # As noted above, you may override +to_xml+ in your ActiveRecord::Base
161
+ # subclasses to have complete control about what's generated. The general
162
+ # form of doing this is:
163
+ #
164
+ # class IHaveMyOwnXML < ActiveRecord::Base
165
+ # def to_xml(options = {})
166
+ # require 'builder'
167
+ # options[:indent] ||= 2
168
+ # xml = options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent])
169
+ # xml.instruct! unless options[:skip_instruct]
170
+ # xml.level_one do
171
+ # xml.tag!(:second_level, 'content')
172
+ # end
173
+ # end
174
+ # end
175
+ def to_xml(options = {}, &block)
176
+ XmlSerializer.new(self, options).serialize(&block)
177
+ end
178
+ end
179
+
180
+ class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
181
+ class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
182
+ def compute_type
183
+ klass = @serializable.class
184
+ cast_type = klass.type_for_attribute(name)
185
+
186
+ type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || cast_type.type
187
+
188
+ { :text => :string,
189
+ :time => :datetime }[type] || type
190
+ end
191
+ protected :compute_type
192
+ end
193
+ end
194
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activemodel-serializers-xml
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Zachary Scott
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.x
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.x
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.x
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.x
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: 5.x
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: 5.x
55
+ - !ruby/object:Gem::Dependency
56
+ name: builder
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sqlite3
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description:
112
+ email:
113
+ - e@zzak.io
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".travis.yml"
120
+ - CONTRIBUTING.md
121
+ - Gemfile
122
+ - MIT-LICENSE
123
+ - README.md
124
+ - Rakefile
125
+ - activemodel-serializers-xml.gemspec
126
+ - lib/active_model-serializers.rb
127
+ - lib/active_model/serializers.rb
128
+ - lib/active_model/serializers/version.rb
129
+ - lib/active_model/serializers/xml.rb
130
+ - lib/active_record/serializers/xml_serializer.rb
131
+ homepage: http://github.com/rails/activemodel-serializers-xml
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.5.1
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: XML serialization for your Active Model objects and Active Record models
155
+ - extracted from Rails
156
+ test_files: []