Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / activerecord / lib / active_record / serialization.rb
blob2c8210a29946f270c4916d8835090d7dd4d39934
1 module ActiveRecord #:nodoc:
2   module Serialization
3     class Serializer #:nodoc:
4       attr_reader :options
6       def initialize(record, options = {})
7         @record, @options = record, options.dup
8       end
10       # To replicate the behavior in ActiveRecord#attributes,
11       # :except takes precedence over :only.  If :only is not set
12       # for a N level model but is set for the N+1 level models,
13       # then because :except is set to a default value, the second
14       # level model can have both :except and :only set.  So if
15       # :only is set, always delete :except.
16       def serializable_attribute_names
17         attribute_names = @record.attribute_names
19         if options[:only]
20           options.delete(:except)
21           attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
22         else
23           options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column)
24           attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
25         end
27         attribute_names
28       end
30       def serializable_method_names
31         Array(options[:methods]).inject([]) do |method_attributes, name|
32           method_attributes << name if @record.respond_to?(name.to_s)
33           method_attributes
34         end
35       end
37       def serializable_names
38         serializable_attribute_names + serializable_method_names
39       end
41       # Add associations specified via the :includes option.
42       # Expects a block that takes as arguments:
43       #   +association+ - name of the association
44       #   +records+     - the association record(s) to be serialized
45       #   +opts+        - options for the association records
46       def add_includes(&block)
47         if include_associations = options.delete(:include)
48           base_only_or_except = { :except => options[:except],
49                                   :only => options[:only] }
51           include_has_options = include_associations.is_a?(Hash)
52           associations = include_has_options ? include_associations.keys : Array(include_associations)
54           for association in associations
55             records = case @record.class.reflect_on_association(association).macro
56             when :has_many, :has_and_belongs_to_many
57               @record.send(association).to_a
58             when :has_one, :belongs_to
59               @record.send(association)
60             end
62             unless records.nil?
63               association_options = include_has_options ? include_associations[association] : base_only_or_except
64               opts = options.merge(association_options)
65               yield(association, records, opts)
66             end
67           end
69           options[:include] = include_associations
70         end
71       end
73       def serializable_record
74         returning(serializable_record = {}) do
75           serializable_names.each { |name| serializable_record[name] = @record.send(name) }
76           add_includes do |association, records, opts|
77             if records.is_a?(Enumerable)
78               serializable_record[association] = records.collect { |r| self.class.new(r, opts).serializable_record }
79             else
80               serializable_record[association] = self.class.new(records, opts).serializable_record
81             end
82           end
83         end
84       end
86       def serialize
87         # overwrite to implement
88       end
90       def to_s(&block)
91         serialize(&block)
92       end
93     end
94   end
95 end
97 require 'active_record/serializers/xml_serializer'
98 require 'active_record/serializers/json_serializer'