class ActiveRecord::Serialization::Serializer

:nodoc:

def add_includes(&block)

+opts+ - options for the association records
+records+ - the association record(s) to be serialized
+association+ - name of the association
Expects a block that takes as arguments:
Add associations specified via the :includes option.
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 initialize(record, options = nil)

def initialize(record, options = nil)
  @record = record
  @options = options ? options.dup : {}
end

def serializable_attribute_names

:only is set, always delete :except.
level model can have both :except and :only set. So if
then because :except is set to a default value, the second
for a N level model but is set for the N+1 level models,
:except takes precedence over :only. If :only is not set
To replicate the behavior in ActiveRecord#attributes,
def serializable_attribute_names
  attribute_names = @record.attribute_names
  if options[:only]
    options.delete(:except)
    attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
  else
    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

def serializable_method_names
  Array(options[:methods]).inject([]) do |method_attributes, name|
    method_attributes << name if @record.respond_to?(name.to_s)
    method_attributes
  end
end

def serializable_names

def serializable_names
  serializable_attribute_names + serializable_method_names
end

def serializable_record

def serializable_record
  {}.tap do |serializable_record|
    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

def serialize
  # overwrite to implement
end

def to_s(&block)

def to_s(&block)
  serialize(&block)
end