Changeset 7663
- Timestamp:
- 09/28/07 14:07:23 (2 years ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/serialization.rb (modified) (5 diffs)
- trunk/activerecord/lib/active_record/serializers/xml_serializer.rb (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r7662 r7663 11 11 * Added the possibility of using symbols in addition to concrete classes with ActiveRecord::Observer#observe #3998 [robbyrussell/tarmo] 12 12 13 * Added ActiveRecord::Base#to_json/from_json (currently does not support :include like to_xml) [DHH]13 * Added ActiveRecord::Base#to_json/from_json [DHH/chuyeow] 14 14 15 15 * Added ActiveRecord::Base#from_xml [DHH]. Example: trunk/activerecord/lib/active_record/serialization.rb
r7519 r7663 3 3 class Serializer #:nodoc: 4 4 attr_reader :options 5 5 6 6 def initialize(record, options = {}) 7 7 @record, @options = record, options.dup … … 24 24 attribute_names = attribute_names - options[:except].collect { |n| n.to_s } 25 25 end 26 26 27 27 attribute_names 28 28 end … … 30 30 def serializable_method_names 31 31 Array(options[:methods]).inject([]) do |method_attributes, name| 32 method_attributes << :name if @record.respond_to?(name.to_s)32 method_attributes << name if @record.respond_to?(name.to_s) 33 33 method_attributes 34 34 end 35 35 end 36 36 37 37 def serializable_names 38 38 serializable_attribute_names + serializable_method_names 39 end 40 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] } 50 51 include_has_options = include_associations.is_a?(Hash) 52 associations = include_has_options ? include_associations.keys : Array(include_associations) 53 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 61 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 68 69 options[:include] = include_associations 70 end 39 71 end 40 72 … … 42 74 returning(serializable_record = {}) do 43 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 44 83 end 45 84 end … … 47 86 def serialize 48 87 # overwrite to implement 49 end 50 88 end 89 51 90 def to_s(&block) 52 91 serialize(&block) trunk/activerecord/lib/active_record/serializers/xml_serializer.rb
r7519 r7663 142 142 options[:skip_instruct] = true 143 143 end 144 144 145 145 builder 146 146 end … … 151 151 dasherize? ? root.dasherize : root 152 152 end 153 153 154 154 def dasherize? 155 155 !options.has_key?(:dasherize) || options[:dasherize] … … 180 180 end 181 181 182 def add_includes183 if include_associations = options.delete(:include)184 root_only_or_except = { :except => options[:except],185 :only => options[:only] }186 187 include_has_options = include_associations.is_a?(Hash)188 189 for association in include_has_options ? include_associations.keys : Array(include_associations)190 association_options = include_has_options ? include_associations[association] : root_only_or_except191 192 opts = options.merge(association_options)193 194 case @record.class.reflect_on_association(association).macro195 when :has_many, :has_and_belongs_to_many196 records = @record.send(association).to_a197 tag = association.to_s198 tag = tag.dasherize if dasherize?199 if records.empty?200 builder.tag!(tag, :type => :array)201 else202 builder.tag!(tag, :type => :array) do203 association_name = association.to_s.singularize204 records.each do |record|205 record.to_xml opts.merge(206 :root => association_name,207 :type => (record.class.to_s.underscore == association_name ? nil : record.class.name)208 )209 end210 end211 end212 when :has_one, :belongs_to213 if record = @record.send(association)214 record.to_xml(opts.merge(:root => association))215 end216 end217 end218 219 options[:include] = include_associations220 end221 end222 223 182 def add_procs 224 183 if procs = options.delete(:procs) … … 228 187 end 229 188 end 230 231 189 232 190 def add_tag(attribute) … … 238 196 end 239 197 198 def add_associations(association, records, opts) 199 if records.is_a?(Enumerable) 200 tag = association.to_s 201 tag = tag.dasherize if dasherize? 202 if records.empty? 203 builder.tag!(tag, :type => :array) 204 else 205 builder.tag!(tag, :type => :array) do 206 association_name = association.to_s.singularize 207 records.each do |record| 208 record.to_xml opts.merge( 209 :root => association_name, 210 :type => (record.class.to_s.underscore == association_name ? nil : record.class.name) 211 ) 212 end 213 end 214 end 215 else 216 if record = @record.send(association) 217 record.to_xml(opts.merge(:root => association)) 218 end 219 end 220 end 221 240 222 def serialize 241 223 args = [root] … … 243 225 args << {:xmlns=>options[:namespace]} 244 226 end 245 227 246 228 if options[:type] 247 229 args << {:type=>options[:type]} 248 230 end 249 231 250 232 builder.tag!(*args) do 251 233 add_attributes 252 add_includes 234 add_includes { |association, records, opts| add_associations(association, records, opts) } 253 235 add_procs 254 236 yield builder if block_given? 255 237 end 256 end 238 end 257 239 258 240 class Attribute #:nodoc: 259 241 attr_reader :name, :value, :type 260 242 261 243 def initialize(name, record) 262 244 @name, @record = name, record 263 245 264 246 @type = compute_type 265 247 @value = compute_value … … 278 260 ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type) 279 261 end 280 262 281 263 def decorations(include_types = true) 282 264 decorations = {} … … 285 267 decorations[:encoding] = 'base64' 286 268 end 287 269 288 270 if include_types && type != :string 289 271 decorations[:type] = type 290 272 end 291 273 292 274 decorations 293 275 end 294 276 295 277 protected 296 278 def compute_type … … 306 288 end 307 289 end 308 290 309 291 def compute_value 310 292 value = @record.send(name) 311 293 312 294 if formatter = Hash::XML_FORMATTING[type.to_s] 313 295 value ? formatter.call(value) : nil