From c6bc8e662614be711f45a8d4b231d5f993b024a7 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 13 Aug 2009 22:27:09 -0500 Subject: Break up concerns for choosing what attributes should be serialized and the actual serializer --- activerecord/lib/active_record/serialization.rb | 80 +++++++++++----------- .../active_record/serializers/json_serializer.rb | 14 ---- .../active_record/serializers/xml_serializer.rb | 19 ++--- 3 files changed, 49 insertions(+), 64 deletions(-) delete mode 100644 activerecord/lib/active_record/serializers/json_serializer.rb (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb index 94f1e8f1fd..b49471f7ab 100644 --- a/activerecord/lib/active_record/serialization.rb +++ b/activerecord/lib/active_record/serialization.rb @@ -1,60 +1,58 @@ module ActiveRecord #:nodoc: module Serialization - module RecordSerializer #:nodoc: - def initialize(*args) - super - options[:except] |= Array.wrap(@serializable.class.inheritance_column) + extend ActiveSupport::Concern + include ActiveModel::Serializers::JSON + + def serializable_hash(options = nil) + options ||= {} + + options[:except] = Array.wrap(options[:except]).map { |n| n.to_s } + options[:except] |= Array.wrap(self.class.inheritance_column) + + hash = super(options) + + serializable_add_includes(options) do |association, records, opts| + hash[association] = records.is_a?(Enumerable) ? + records.map { |r| r.serializable_hash(opts) } : + records.serializable_hash(opts) end + hash + end + + private # Add associations specified via the :includes 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 add_includes(&block) - if include_associations = options.delete(:include) - base_only_or_except = { :except => options[:except], - :only => options[:only] } - - include_has_options = include_associations.is_a?(Hash) - associations = include_has_options ? include_associations.keys : Array.wrap(include_associations) - - for association in associations - records = case @serializable.class.reflect_on_association(association).macro - when :has_many, :has_and_belongs_to_many - @serializable.send(association).to_a - when :has_one, :belongs_to - @serializable.send(association) - end - - unless records.nil? - association_options = include_has_options ? include_associations[association] : base_only_or_except - opts = options.merge(association_options) - yield(association, records, opts) - end - end + def serializable_add_includes(options = {}) + return unless include_associations = options.delete(:include) - options[:include] = include_associations - end - end + base_only_or_except = { :except => options[:except], + :only => options[:only] } + + include_has_options = include_associations.is_a?(Hash) + associations = include_has_options ? include_associations.keys : Array.wrap(include_associations) - def serializable_hash - hash = super + for association in associations + records = case self.class.reflect_on_association(association).macro + when :has_many, :has_and_belongs_to_many + send(association).to_a + when :has_one, :belongs_to + send(association) + end - add_includes do |association, records, opts| - hash[association] = - if records.is_a?(Enumerable) - records.collect { |r| self.class.new(r, opts).serializable_hash } - else - self.class.new(records, opts).serializable_hash - end + unless records.nil? + association_options = include_has_options ? include_associations[association] : base_only_or_except + opts = options.merge(association_options) + yield(association, records, opts) + end end - hash + options[:include] = include_associations end - end end end require 'active_record/serializers/xml_serializer' -require 'active_record/serializers/json_serializer' diff --git a/activerecord/lib/active_record/serializers/json_serializer.rb b/activerecord/lib/active_record/serializers/json_serializer.rb deleted file mode 100644 index 63bf42c09d..0000000000 --- a/activerecord/lib/active_record/serializers/json_serializer.rb +++ /dev/null @@ -1,14 +0,0 @@ -module ActiveRecord #:nodoc: - module Serialization - extend ActiveSupport::Concern - include ActiveModel::Serializers::JSON - - class JSONSerializer < ActiveModel::Serializers::JSON::Serializer - include Serialization::RecordSerializer - end - - def encode_json(encoder) - JSONSerializer.new(self, encoder.options).to_s - end - end -end diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index 4e172bd2b6..b19920741e 100644 --- a/activerecord/lib/active_record/serializers/xml_serializer.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -2,6 +2,8 @@ require 'active_support/core_ext/hash/conversions' module ActiveRecord #:nodoc: module Serialization + include ActiveModel::Serializers::Xml + # Builds an XML document to represent the model. Some configuration is # available through +options+. However more complicated cases should # override ActiveRecord::Base#to_xml. @@ -169,18 +171,15 @@ module ActiveRecord #:nodoc: # end # end def to_xml(options = {}, &block) - serializer = XmlSerializer.new(self, options) - block_given? ? serializer.to_s(&block) : serializer.to_s - end - - def from_xml(xml) - self.attributes = Hash.from_xml(xml).values.first - self + XmlSerializer.new(self, options).serialize(&block) end end class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: - include Serialization::RecordSerializer + def initialize(*args) + super + options[:except] |= Array.wrap(@serializable.class.inheritance_column) + end def serializable_attributes serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) } @@ -235,7 +234,9 @@ module ActiveRecord #:nodoc: builder.tag!(*args) do add_attributes procs = options.delete(:procs) - add_includes { |association, records, opts| add_associations(association, records, opts) } + @serializable.send(:serializable_add_includes, options) { |association, records, opts| + add_associations(association, records, opts) + } options[:procs] = procs add_procs yield builder if block_given? -- cgit v1.2.3