diff options
Diffstat (limited to 'activerecord/lib/active_record/serialization.rb')
-rw-r--r-- | activerecord/lib/active_record/serialization.rb | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb index f10d1b3b7e..2c8210a299 100644 --- a/activerecord/lib/active_record/serialization.rb +++ b/activerecord/lib/active_record/serialization.rb @@ -2,7 +2,7 @@ module ActiveRecord #:nodoc: module Serialization class Serializer #:nodoc: attr_reader :options - + def initialize(record, options = {}) @record, @options = record, options.dup end @@ -23,31 +23,70 @@ module ActiveRecord #:nodoc: options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column) attribute_names = attribute_names - options[:except].collect { |n| n.to_s } end - + attribute_names end def serializable_method_names Array(options[:methods]).inject([]) do |method_attributes, name| - method_attributes << :name if @record.respond_to?(name.to_s) + method_attributes << name if @record.respond_to?(name.to_s) method_attributes end end - + def serializable_names serializable_attribute_names + serializable_method_names end + # 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(include_associations) + + for association in associations + records = case @record.class.reflect_on_association(association).macro + when :has_many, :has_and_belongs_to_many + @record.send(association).to_a + when :has_one, :belongs_to + @record.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 + + options[:include] = include_associations + end + end + def serializable_record returning(serializable_record = {}) do serializable_names.each { |name| serializable_record[name] = @record.send(name) } + add_includes do |association, records, opts| + if records.is_a?(Enumerable) + serializable_record[association] = records.collect { |r| self.class.new(r, opts).serializable_record } + else + serializable_record[association] = self.class.new(records, opts).serializable_record + end + end end end def serialize # overwrite to implement - end - + end + def to_s(&block) serialize(&block) end |