aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/serialization.rb
diff options
context:
space:
mode:
authorJohn Firebaugh <john_firebaugh@us.ibm.com>2011-02-21 22:55:49 -0800
committerJohn Firebaugh <john_firebaugh@us.ibm.com>2011-07-17 11:34:07 -0700
commit4860143ee4ccafef474f14f40b8f70c2b6b54656 (patch)
tree1fa5a120a4b1d6f79feaf4b7dc18c3c41de6e523 /activemodel/lib/active_model/serialization.rb
parent1723a7a6c6098eaa61ce964bebca2ed5f8f947b7 (diff)
downloadrails-4860143ee4ccafef474f14f40b8f70c2b6b54656.tar.gz
rails-4860143ee4ccafef474f14f40b8f70c2b6b54656.tar.bz2
rails-4860143ee4ccafef474f14f40b8f70c2b6b54656.zip
ActiveModel support for the :include serialization option
This commit moves support for the :include serialization option for serializing associated objects out of ActiveRecord in into ActiveModel. The following methods support the :include option: * serializable_hash * to_json * to_xml Instances must respond to methods named by the values of the :includes array (or keys of the :includes hash). If an association method returns an object that is_a?(Enumerable) (which AR has_many associations do), it is assumed to be a collection association, and its elements must respond to :serializable_hash. Otherwise it must respond to :serializable_hash itself. While here, fix #858, XmlSerializer should not singularize already singular association names.
Diffstat (limited to 'activemodel/lib/active_model/serialization.rb')
-rw-r--r--activemodel/lib/active_model/serialization.rb33
1 files changed, 32 insertions, 1 deletions
diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb
index 0b4067257e..9260c5082d 100644
--- a/activemodel/lib/active_model/serialization.rb
+++ b/activemodel/lib/active_model/serialization.rb
@@ -77,7 +77,38 @@ module ActiveModel
end
method_names = Array.wrap(options[:methods]).select { |n| respond_to?(n) }
- Hash[(attribute_names + method_names).map { |n| [n, send(n)] }]
+ hash = Hash[(attribute_names + method_names).map { |n| [n, send(n)] }]
+
+ serializable_add_includes(options) do |association, records, opts|
+ hash[association] = if records.is_a?(Enumerable)
+ records.map { |a| a.serializable_hash(opts) }
+ else
+ records.serializable_hash(opts)
+ end
+ end
+
+ hash
end
+
+ private
+ # Add associations specified via the <tt>:include</tt> option.
+ #
+ # Expects a block that takes as arguments:
+ # +association+ - name of the association
+ # +records+ - the association record(s) to be serialized
+ # +opts+ - options for the association records
+ def serializable_add_includes(options = {})
+ return unless include = options[:include]
+
+ unless include.is_a?(Hash)
+ include = Hash[Array.wrap(include).map { |n| [n, {}] }]
+ end
+
+ include.each do |association, opts|
+ if records = send(association)
+ yield association, records, opts
+ end
+ end
+ end
end
end