Skip to content
This repository
Browse code

Merge commit 'rails/master'

  • Loading branch information...
commit fb46d00fdfa724dc0c252a46ec13c4ee4cda4708 2 parents 6d4b6a2 + 783db25
Emilio Tagua miloops authored
2  activemodel/lib/active_model.rb
@@ -34,6 +34,7 @@ module ActiveModel
34 34 autoload :Naming, 'active_model/naming'
35 35 autoload :Observer, 'active_model/observing'
36 36 autoload :Observing, 'active_model/observing'
  37 + autoload :Serializer, 'active_model/serializer'
37 38 autoload :StateMachine, 'active_model/state_machine'
38 39 autoload :TestCase, 'active_model/test_case'
39 40 autoload :Validations, 'active_model/validations'
@@ -41,6 +42,7 @@ module ActiveModel
41 42
42 43 module Serializers
43 44 autoload :JSON, 'active_model/serializers/json'
  45 + autoload :Xml, 'active_model/serializers/xml'
44 46 end
45 47 end
46 48
8 activemodel/lib/active_model/attributes.rb
@@ -2,6 +2,14 @@
2 2
3 3 module ActiveModel
4 4 module Attributes
  5 + def self.append_features(base)
  6 + unless base.instance_methods.include?('attributes')
  7 + super
  8 + else
  9 + false
  10 + end
  11 + end
  12 +
5 13 def attributes
6 14 instance_values
7 15 end
60 activemodel/lib/active_model/serializer.rb
... ... @@ -0,0 +1,60 @@
  1 +require 'active_support/core_ext/hash/except'
  2 +require 'active_support/core_ext/hash/slice'
  3 +
  4 +module ActiveModel
  5 + class Serializer
  6 + attr_reader :options
  7 +
  8 + def initialize(serializable, options = nil)
  9 + @serializable = serializable
  10 + @options = options ? options.dup : {}
  11 +
  12 + @options[:only] = Array.wrap(@options[:only]).map { |n| n.to_s }
  13 + @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s }
  14 + end
  15 +
  16 + def serialize
  17 + raise NotImplemented
  18 + end
  19 +
  20 + def to_s(&block)
  21 + serialize(&block)
  22 + end
  23 +
  24 + # To replicate the behavior in ActiveRecord#attributes,
  25 + # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
  26 + # for a N level model but is set for the N+1 level models,
  27 + # then because <tt>:except</tt> is set to a default value, the second
  28 + # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
  29 + # <tt>:only</tt> is set, always delete <tt>:except</tt>.
  30 + def serializable_attribute_names
  31 + attribute_names = @serializable.attributes.keys.sort
  32 +
  33 + if options[:only].any?
  34 + attribute_names &= options[:only]
  35 + elsif options[:except].any?
  36 + attribute_names -= options[:except]
  37 + end
  38 +
  39 + attribute_names
  40 + end
  41 +
  42 + def serializable_method_names
  43 + Array.wrap(options[:methods]).inject([]) do |methods, name|
  44 + methods << name if @serializable.respond_to?(name.to_s)
  45 + methods
  46 + end
  47 + end
  48 +
  49 + def serializable_names
  50 + serializable_attribute_names + serializable_method_names
  51 + end
  52 +
  53 + def serializable_hash
  54 + serializable_names.inject({}) { |hash, name|
  55 + hash[name] = @serializable.send(name)
  56 + hash
  57 + }
  58 + end
  59 + end
  60 +end
101 activemodel/lib/active_model/serializers/json.rb
... ... @@ -1,7 +1,5 @@
1 1 require 'active_support/json'
2 2 require 'active_support/core_ext/class/attribute_accessors'
3   -require 'active_support/core_ext/hash/except'
4   -require 'active_support/core_ext/hash/slice'
5 3
6 4 module ActiveModel
7 5 module Serializers
@@ -10,29 +8,102 @@ module JSON
10 8 include ActiveModel::Attributes
11 9
12 10 included do
  11 + extend ActiveModel::Naming
  12 +
13 13 cattr_accessor :include_root_in_json, :instance_writer => false
14 14 end
15 15
16   - def encode_json(encoder)
17   - options = encoder.options || {}
18   -
19   - hash = if options[:only]
20   - only = Array.wrap(options[:only]).map { |attr| attr.to_s }
21   - attributes.slice(*only)
22   - elsif options[:except]
23   - except = Array.wrap(options[:except]).map { |attr| attr.to_s }
24   - attributes.except(*except)
25   - else
26   - attributes
  16 + class Serializer < ActiveModel::Serializer
  17 + def serializable_hash
  18 + model = super
  19 + @serializable.include_root_in_json ?
  20 + { @serializable.class.model_name.element => model } :
  21 + model
27 22 end
28 23
29   - hash = { self.class.model_name.element => hash } if include_root_in_json
30   - ActiveSupport::JSON.encode(hash)
  24 + def serialize
  25 + ActiveSupport::JSON.encode(serializable_hash)
  26 + end
  27 + end
  28 +
  29 + # Returns a JSON string representing the model. Some configuration is
  30 + # available through +options+.
  31 + #
  32 + # The option <tt>ActiveRecord::Base.include_root_in_json</tt> controls the
  33 + # top-level behavior of to_json. In a new Rails application, it is set to
  34 + # <tt>true</tt> in initializers/new_rails_defaults.rb. When it is <tt>true</tt>,
  35 + # to_json will emit a single root node named after the object's type. For example:
  36 + #
  37 + # konata = User.find(1)
  38 + # ActiveRecord::Base.include_root_in_json = true
  39 + # konata.to_json
  40 + # # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
  41 + # "created_at": "2006/08/01", "awesome": true} }
  42 + #
  43 + # ActiveRecord::Base.include_root_in_json = false
  44 + # konata.to_json
  45 + # # => {"id": 1, "name": "Konata Izumi", "age": 16,
  46 + # "created_at": "2006/08/01", "awesome": true}
  47 + #
  48 + # The remainder of the examples in this section assume include_root_in_json is set to
  49 + # <tt>false</tt>.
  50 + #
  51 + # Without any +options+, the returned JSON string will include all
  52 + # the model's attributes. For example:
  53 + #
  54 + # konata = User.find(1)
  55 + # konata.to_json
  56 + # # => {"id": 1, "name": "Konata Izumi", "age": 16,
  57 + # "created_at": "2006/08/01", "awesome": true}
  58 + #
  59 + # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
  60 + # included, and work similar to the +attributes+ method. For example:
  61 + #
  62 + # konata.to_json(:only => [ :id, :name ])
  63 + # # => {"id": 1, "name": "Konata Izumi"}
  64 + #
  65 + # konata.to_json(:except => [ :id, :created_at, :age ])
  66 + # # => {"name": "Konata Izumi", "awesome": true}
  67 + #
  68 + # To include any methods on the model, use <tt>:methods</tt>.
  69 + #
  70 + # konata.to_json(:methods => :permalink)
  71 + # # => {"id": 1, "name": "Konata Izumi", "age": 16,
  72 + # "created_at": "2006/08/01", "awesome": true,
  73 + # "permalink": "1-konata-izumi"}
  74 + #
  75 + # To include associations, use <tt>:include</tt>.
  76 + #
  77 + # konata.to_json(:include => :posts)
  78 + # # => {"id": 1, "name": "Konata Izumi", "age": 16,
  79 + # "created_at": "2006/08/01", "awesome": true,
  80 + # "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
  81 + # {"id": 2, author_id: 1, "title": "So I was thinking"}]}
  82 + #
  83 + # 2nd level and higher order associations work as well:
  84 + #
  85 + # konata.to_json(:include => { :posts => {
  86 + # :include => { :comments => {
  87 + # :only => :body } },
  88 + # :only => :title } })
  89 + # # => {"id": 1, "name": "Konata Izumi", "age": 16,
  90 + # "created_at": "2006/08/01", "awesome": true,
  91 + # "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
  92 + # "title": "Welcome to the weblog"},
  93 + # {"comments": [{"body": "Don't think too hard"}],
  94 + # "title": "So I was thinking"}]}
  95 + def encode_json(encoder)
  96 + Serializer.new(self, encoder.options).to_s
31 97 end
32 98
33 99 def as_json(options = nil)
34 100 self
35 101 end
  102 +
  103 + def from_json(json)
  104 + self.attributes = ActiveSupport::JSON.decode(json)
  105 + self
  106 + end
36 107 end
37 108 end
38 109 end
168 activemodel/lib/active_model/serializers/xml.rb
... ... @@ -0,0 +1,168 @@
  1 +require 'active_support/core_ext/class/attribute_accessors'
  2 +require 'active_support/core_ext/hash/conversions'
  3 +
  4 +module ActiveModel
  5 + module Serializers
  6 + module Xml
  7 + extend ActiveSupport::Concern
  8 + include ActiveModel::Attributes
  9 +
  10 + class Serializer < ActiveModel::Serializer #:nodoc:
  11 + class Attribute #:nodoc:
  12 + attr_reader :name, :value, :type
  13 +
  14 + def initialize(name, serializable)
  15 + @name, @serializable = name, serializable
  16 + @type = compute_type
  17 + @value = compute_value
  18 + end
  19 +
  20 + def needs_encoding?
  21 + ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
  22 + end
  23 +
  24 + def decorations(include_types = true)
  25 + decorations = {}
  26 +
  27 + if type == :binary
  28 + decorations[:encoding] = 'base64'
  29 + end
  30 +
  31 + if include_types && type != :string
  32 + decorations[:type] = type
  33 + end
  34 +
  35 + if value.nil?
  36 + decorations[:nil] = true
  37 + end
  38 +
  39 + decorations
  40 + end
  41 +
  42 + protected
  43 + def compute_type
  44 + value = @serializable.send(name)
  45 + type = Hash::XML_TYPE_NAMES[value.class.name]
  46 + type ||= :string if value.respond_to?(:to_str)
  47 + type ||= :yaml
  48 + type
  49 + end
  50 +
  51 + def compute_value
  52 + value = @serializable.send(name)
  53 +
  54 + if formatter = Hash::XML_FORMATTING[type.to_s]
  55 + value ? formatter.call(value) : nil
  56 + else
  57 + value
  58 + end
  59 + end
  60 + end
  61 +
  62 + class MethodAttribute < Attribute #:nodoc:
  63 + protected
  64 + def compute_type
  65 + Hash::XML_TYPE_NAMES[@serializable.send(name).class.name] || :string
  66 + end
  67 + end
  68 +
  69 + def builder
  70 + @builder ||= begin
  71 + require 'builder' unless defined? ::Builder
  72 + options[:indent] ||= 2
  73 + builder = options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])
  74 +
  75 + unless options[:skip_instruct]
  76 + builder.instruct!
  77 + options[:skip_instruct] = true
  78 + end
  79 +
  80 + builder
  81 + end
  82 + end
  83 +
  84 + def root
  85 + root = (options[:root] || @serializable.class.to_s.underscore).to_s
  86 + reformat_name(root)
  87 + end
  88 +
  89 + def dasherize?
  90 + !options.has_key?(:dasherize) || options[:dasherize]
  91 + end
  92 +
  93 + def camelize?
  94 + options.has_key?(:camelize) && options[:camelize]
  95 + end
  96 +
  97 + def serializable_attributes
  98 + serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) }
  99 + end
  100 +
  101 + def serializable_method_attributes
  102 + Array(options[:methods]).inject([]) do |methods, name|
  103 + methods << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
  104 + methods
  105 + end
  106 + end
  107 +
  108 + def add_attributes
  109 + (serializable_attributes + serializable_method_attributes).each do |attribute|
  110 + add_tag(attribute)
  111 + end
  112 + end
  113 +
  114 + def add_procs
  115 + if procs = options.delete(:procs)
  116 + [ *procs ].each do |proc|
  117 + proc.call(options)
  118 + end
  119 + end
  120 + end
  121 +
  122 + def add_tag(attribute)
  123 + builder.tag!(
  124 + reformat_name(attribute.name),
  125 + attribute.value.to_s,
  126 + attribute.decorations(!options[:skip_types])
  127 + )
  128 + end
  129 +
  130 + def serialize
  131 + args = [root]
  132 +
  133 + if options[:namespace]
  134 + args << {:xmlns => options[:namespace]}
  135 + end
  136 +
  137 + if options[:type]
  138 + args << {:type => options[:type]}
  139 + end
  140 +
  141 + builder.tag!(*args) do
  142 + add_attributes
  143 + procs = options.delete(:procs)
  144 + options[:procs] = procs
  145 + add_procs
  146 + yield builder if block_given?
  147 + end
  148 + end
  149 +
  150 + private
  151 + def reformat_name(name)
  152 + name = name.camelize if camelize?
  153 + dasherize? ? name.dasherize : name
  154 + end
  155 + end
  156 +
  157 + def to_xml(options = {}, &block)
  158 + serializer = Serializer.new(self, options)
  159 + block_given? ? serializer.to_s(&block) : serializer.to_s
  160 + end
  161 +
  162 + def from_xml(xml)
  163 + self.attributes = Hash.from_xml(xml).values.first
  164 + self
  165 + end
  166 + end
  167 + end
  168 +end
25 activemodel/test/cases/json_serialization_test.rb → .../cases/serializeration/json_serialization_test.rb
... ... @@ -1,12 +1,11 @@
1 1 require 'cases/helper'
  2 +require 'models/contact'
2 3
3   -class JsonSerializationTest < ActiveModel::TestCase
4   - class Contact
5   - extend ActiveModel::Naming
6   - include ActiveModel::Serializers::JSON
7   - attr_accessor :name, :age, :created_at, :awesome, :preferences
8   - end
  4 +class Contact
  5 + include ActiveModel::Serializers::JSON
  6 +end
9 7
  8 +class JsonSerializationTest < ActiveModel::TestCase
10 9 def setup
11 10 @contact = Contact.new
12 11 @contact.name = 'Konata Izumi'
@@ -61,4 +60,18 @@ def setup
61 60 assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
62 61 assert_match %r{"preferences":\{"shows":"anime"\}}, json
63 62 end
  63 +
  64 + test "methds are called on object" do
  65 + # Define methods on fixture.
  66 + def @contact.label; "Has cheezburger"; end
  67 + def @contact.favorite_quote; "Constraints are liberating"; end
  68 +
  69 + # Single method.
  70 + assert_match %r{"label":"Has cheezburger"}, @contact.to_json(:only => :name, :methods => :label)
  71 +
  72 + # Both methods.
  73 + methods_json = @contact.to_json(:only => :name, :methods => [:label, :favorite_quote])
  74 + assert_match %r{"label":"Has cheezburger"}, methods_json
  75 + assert_match %r{"favorite_quote":"Constraints are liberating"}, methods_json
  76 + end
64 77 end
81 activemodel/test/cases/serializeration/xml_serialization_test.rb
... ... @@ -0,0 +1,81 @@
  1 +require 'cases/helper'
  2 +require 'models/contact'
  3 +
  4 +class Contact
  5 + include ActiveModel::Serializers::Xml
  6 +end
  7 +
  8 +class XmlSerializationTest < ActiveModel::TestCase
  9 + def setup
  10 + @contact = Contact.new
  11 + @contact.name = 'aaron stack'
  12 + @contact.age = 25
  13 + @contact.created_at = Time.utc(2006, 8, 1)
  14 + @contact.awesome = false
  15 + @contact.preferences = { :gem => 'ruby' }
  16 + end
  17 +
  18 + test "should serialize default root" do
  19 + @xml = @contact.to_xml
  20 + assert_match %r{^<contact>}, @xml
  21 + assert_match %r{</contact>$}, @xml
  22 + end
  23 +
  24 + test "should serialize default root with namespace" do
  25 + @xml = @contact.to_xml :namespace => "http://xml.rubyonrails.org/contact"
  26 + assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, @xml
  27 + assert_match %r{</contact>$}, @xml
  28 + end
  29 +
  30 + test "should serialize custom root" do
  31 + @xml = @contact.to_xml :root => 'xml_contact'
  32 + assert_match %r{^<xml-contact>}, @xml
  33 + assert_match %r{</xml-contact>$}, @xml
  34 + end
  35 +
  36 + test "should allow undasherized tags" do
  37 + @xml = @contact.to_xml :root => 'xml_contact', :dasherize => false
  38 + assert_match %r{^<xml_contact>}, @xml
  39 + assert_match %r{</xml_contact>$}, @xml
  40 + assert_match %r{<created_at}, @xml
  41 + end
  42 +
  43 + test "should allow camelized tags" do
  44 + @xml = @contact.to_xml :root => 'xml_contact', :camelize => true
  45 + assert_match %r{^<XmlContact>}, @xml
  46 + assert_match %r{</XmlContact>$}, @xml
  47 + assert_match %r{<CreatedAt}, @xml
  48 + end
  49 +
  50 + test "should allow skipped types" do
  51 + @xml = @contact.to_xml :skip_types => true
  52 + assert %r{<age>25</age>}.match(@xml)
  53 + end
  54 +
  55 + test "should include yielded additions" do
  56 + @xml = @contact.to_xml do |xml|
  57 + xml.creator "David"
  58 + end
  59 + assert_match %r{<creator>David</creator>}, @xml
  60 + end
  61 +
  62 + test "should serialize string" do
  63 + assert_match %r{<name>aaron stack</name>}, @contact.to_xml
  64 + end
  65 +
  66 + test "should serialize integer" do
  67 + assert_match %r{<age type="integer">25</age>}, @contact.to_xml
  68 + end
  69 +
  70 + test "should serialize datetime" do
  71 + assert_match %r{<created-at type=\"datetime\">2006-08-01T00:00:00Z</created-at>}, @contact.to_xml
  72 + end
  73 +
  74 + test "should serialize boolean" do
  75 + assert_match %r{<awesome type=\"boolean\">false</awesome>}, @contact.to_xml
  76 + end
  77 +
  78 + test "should serialize yaml" do
  79 + assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @contact.to_xml
  80 + end
  81 +end
3  activemodel/test/models/contact.rb
... ... @@ -0,0 +1,3 @@
  1 +class Contact
  2 + attr_accessor :name, :age, :created_at, :awesome, :preferences
  3 +end
68 activerecord/lib/active_record/serialization.rb
... ... @@ -1,42 +1,9 @@
1 1 module ActiveRecord #:nodoc:
2 2 module Serialization
3   - class Serializer #:nodoc:
4   - attr_reader :options
5   -
6   - def initialize(record, options = nil)
7   - @record = record
8   - @options = options ? options.dup : {}
9   - end
10   -
11   - # To replicate the behavior in ActiveRecord#attributes,
12   - # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
13   - # for a N level model but is set for the N+1 level models,
14   - # then because <tt>:except</tt> is set to a default value, the second
15   - # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
16   - # <tt>:only</tt> is set, always delete <tt>:except</tt>.
17   - def serializable_attribute_names
18   - attribute_names = @record.attribute_names
19   -
20   - if options[:only]
21   - options.delete(:except)
22   - attribute_names = attribute_names & Array.wrap(options[:only]).collect { |n| n.to_s }
23   - else
24   - options[:except] = Array.wrap(options[:except]) | Array.wrap(@record.class.inheritance_column)
25   - attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
26   - end
27   -
28   - attribute_names
29   - end
30   -
31   - def serializable_method_names
32   - Array.wrap(options[:methods]).inject([]) do |method_attributes, name|
33   - method_attributes << name if @record.respond_to?(name.to_s)
34   - method_attributes
35   - end
36   - end
37   -
38   - def serializable_names
39   - serializable_attribute_names + serializable_method_names
  3 + module RecordSerializer #:nodoc:
  4 + def initialize(*args)
  5 + super
  6 + options[:except] |= Array.wrap(@serializable.class.inheritance_column)
40 7 end
41 8
42 9 # Add associations specified via the <tt>:includes</tt> option.
@@ -53,11 +20,11 @@ def add_includes(&block)
53 20 associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
54 21
55 22 for association in associations
56   - records = case @record.class.reflect_on_association(association).macro
  23 + records = case @serializable.class.reflect_on_association(association).macro
57 24 when :has_many, :has_and_belongs_to_many
58   - @record.send(association).to_a
  25 + @serializable.send(association).to_a
59 26 when :has_one, :belongs_to
60   - @record.send(association)
  27 + @serializable.send(association)
61 28 end
62 29
63 30 unless records.nil?
@@ -71,28 +38,19 @@ def add_includes(&block)
71 38 end
72 39 end
73 40
74   - def serializable_record
75   - record = {}
76   - serializable_names.each { |name| record[name] = @record.send(name) }
  41 + def serializable_hash
  42 + hash = super
77 43
78 44 add_includes do |association, records, opts|
79   - record[association] =
  45 + hash[association] =
80 46 if records.is_a?(Enumerable)
81   - records.collect { |r| self.class.new(r, opts).serializable_record }
  47 + records.collect { |r| self.class.new(r, opts).serializable_hash }
82 48 else
83   - self.class.new(records, opts).serializable_record
  49 + self.class.new(records, opts).serializable_hash
84 50 end
85 51 end
86 52
87   - record
88   - end
89   -
90   - def serialize
91   - # overwrite to implement
92   - end
93   -
94   - def to_s(&block)
95   - serialize(&block)
  53 + hash
96 54 end
97 55 end
98 56 end
85 activerecord/lib/active_record/serializers/json_serializer.rb
... ... @@ -1,91 +1,14 @@
1   -require 'active_support/json'
2   -require 'active_model/naming'
3   -
4 1 module ActiveRecord #:nodoc:
5 2 module Serialization
6 3 extend ActiveSupport::Concern
  4 + include ActiveModel::Serializers::JSON
7 5
8   - included do
9   - cattr_accessor :include_root_in_json, :instance_writer => false
  6 + class JSONSerializer < ActiveModel::Serializers::JSON::Serializer
  7 + include Serialization::RecordSerializer
10 8 end
11 9
12   - # Returns a JSON string representing the model. Some configuration is
13   - # available through +options+.
14   - #
15   - # The option <tt>ActiveRecord::Base.include_root_in_json</tt> controls the
16   - # top-level behavior of to_json. In a new Rails application, it is set to
17   - # <tt>true</tt> in initializers/new_rails_defaults.rb. When it is <tt>true</tt>,
18   - # to_json will emit a single root node named after the object's type. For example:
19   - #
20   - # konata = User.find(1)
21   - # ActiveRecord::Base.include_root_in_json = true
22   - # konata.to_json
23   - # # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
24   - # "created_at": "2006/08/01", "awesome": true} }
25   - #
26   - # ActiveRecord::Base.include_root_in_json = false
27   - # konata.to_json
28   - # # => {"id": 1, "name": "Konata Izumi", "age": 16,
29   - # "created_at": "2006/08/01", "awesome": true}
30   - #
31   - # The remainder of the examples in this section assume include_root_in_json is set to
32   - # <tt>false</tt>.
33   - #
34   - # Without any +options+, the returned JSON string will include all
35   - # the model's attributes. For example:
36   - #
37   - # konata = User.find(1)
38   - # konata.to_json
39   - # # => {"id": 1, "name": "Konata Izumi", "age": 16,
40   - # "created_at": "2006/08/01", "awesome": true}
41   - #
42   - # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
43   - # included, and work similar to the +attributes+ method. For example:
44   - #
45   - # konata.to_json(:only => [ :id, :name ])
46   - # # => {"id": 1, "name": "Konata Izumi"}
47   - #
48   - # konata.to_json(:except => [ :id, :created_at, :age ])
49   - # # => {"name": "Konata Izumi", "awesome": true}
50   - #
51   - # To include any methods on the model, use <tt>:methods</tt>.
52   - #
53   - # konata.to_json(:methods => :permalink)
54   - # # => {"id": 1, "name": "Konata Izumi", "age": 16,
55   - # "created_at": "2006/08/01", "awesome": true,
56   - # "permalink": "1-konata-izumi"}
57   - #
58   - # To include associations, use <tt>:include</tt>.
59   - #
60   - # konata.to_json(:include => :posts)
61   - # # => {"id": 1, "name": "Konata Izumi", "age": 16,
62   - # "created_at": "2006/08/01", "awesome": true,
63   - # "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
64   - # {"id": 2, author_id: 1, "title": "So I was thinking"}]}
65   - #
66   - # 2nd level and higher order associations work as well:
67   - #
68   - # konata.to_json(:include => { :posts => {
69   - # :include => { :comments => {
70   - # :only => :body } },
71   - # :only => :title } })
72   - # # => {"id": 1, "name": "Konata Izumi", "age": 16,
73   - # "created_at": "2006/08/01", "awesome": true,
74   - # "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
75   - # "title": "Welcome to the weblog"},
76   - # {"comments": [{"body": "Don't think too hard"}],
77   - # "title": "So I was thinking"}]}
78 10 def encode_json(encoder)
79   - hash = Serializer.new(self, encoder.options).serializable_record
80   - hash = { self.class.model_name.element => hash } if include_root_in_json
81   - ActiveSupport::JSON.encode(hash)
82   - end
83   -
84   - def as_json(options = nil) self end #:nodoc:
85   -
86   - def from_json(json)
87   - self.attributes = ActiveSupport::JSON.decode(json)
88   - self
  11 + JSONSerializer.new(self, encoder.options).to_s
89 12 end
90 13 end
91 14 end
12 activerecord/lib/active_record/serializers/xml_serializer.rb
@@ -164,7 +164,9 @@ def from_xml(xml)
164 164 end
165 165 end
166 166
167   - class XmlSerializer < ActiveRecord::Serialization::Serializer #:nodoc:
  167 + class XmlSerializer < ActiveModel::Serializer #:nodoc:
  168 + include Serialization::RecordSerializer
  169 +
168 170 def builder
169 171 @builder ||= begin
170 172 require 'builder' unless defined? ::Builder
@@ -181,7 +183,7 @@ def builder
181 183 end
182 184
183 185 def root
184   - root = (options[:root] || @record.class.to_s.underscore).to_s
  186 + root = (options[:root] || @serializable.class.to_s.underscore).to_s
185 187 reformat_name(root)
186 188 end
187 189
@@ -199,12 +201,12 @@ def reformat_name(name)
199 201 end
200 202
201 203 def serializable_attributes
202   - serializable_attribute_names.collect { |name| Attribute.new(name, @record) }
  204 + serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) }
203 205 end
204 206
205 207 def serializable_method_attributes
206 208 Array(options[:methods]).inject([]) do |method_attributes, name|
207   - method_attributes << MethodAttribute.new(name.to_s, @record) if @record.respond_to?(name.to_s)
  209 + method_attributes << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
208 210 method_attributes
209 211 end
210 212 end
@@ -254,7 +256,7 @@ def add_associations(association, records, opts)
254 256 end
255 257 end
256 258 else
257   - if record = @record.send(association)
  259 + if record = @serializable.send(association)
258 260 record.to_xml(opts.merge(:root => association))
259 261 end
260 262 end

0 comments on commit fb46d00

Please sign in to comment.
Something went wrong with that request. Please try again.