1 module ActiveRecord
#:nodoc:
3 class Serializer
#:nodoc:
6 def initialize(record
, options
= {})
7 @record, @options = record
, options
.dup
10 # To replicate the behavior in ActiveRecord#attributes,
11 # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
12 # for a N level model but is set for the N+1 level models,
13 # then because <tt>:except</tt> is set to a default value, the second
14 # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
15 # <tt>:only</tt> is set, always delete <tt>:except</tt>.
16 def serializable_attribute_names
17 attribute_names
= @record.attribute_names
20 options
.delete(:except)
21 attribute_names
= attribute_names
& Array(options
[:only]).collect
{ |n
| n
.to_s
}
23 options
[:except] = Array(options
[:except]) | Array(@record.class.inheritance_column
)
24 attribute_names
= attribute_names
- options
[:except].collect
{ |n
| n
.to_s
}
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
)
37 def serializable_names
38 serializable_attribute_names
+ serializable_method_names
41 # Add associations specified via the <tt>:includes</tt> 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
)
63 association_options
= include_has_options
? include_associations
[association
] : base_only_or_except
64 opts
= options
.merge(association_options
)
65 yield(association
, records
, opts
)
69 options
[:include] = include_associations
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
}
80 serializable_record
[association
] = self.class.new(records
, opts
).serializable_record
87 # overwrite to implement
97 require 'active_record/serializers/xml_serializer'
98 require 'active_record/serializers/json_serializer'