<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -2,6 +2,14 @@ require 'active_support/core_ext/object/instance_variables'
 
 module ActiveModel
   module Attributes
+    def self.append_features(base)
+      unless base.instance_methods.include?('attributes')
+        super
+      else
+        false
+      end
+    end
+
     def attributes
       instance_values
     end</diff>
      <filename>activemodel/lib/active_model/attributes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,6 +8,9 @@ module ActiveModel
     def initialize(serializable, options = nil)
       @serializable = serializable
       @options = options ? options.dup : {}
+
+      @options[:only] = Array.wrap(@options[:only]).map { |n| n.to_s }
+      @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s }
     end
 
     def serialize
@@ -18,37 +21,40 @@ module ActiveModel
       serialize(&amp;block)
     end
 
-    protected
-      def serializable_attribute_names
-        attribute_names = @serializable.attributes.keys
-
-        if options[:only]
-          only = Array.wrap(options[:only]).map { |n| n.to_s }
-          attribute_names &amp;= only
-        elsif options[:except]
-          except = Array.wrap(options[:except]).map { |n| n.to_s }
-          attribute_names -= except
-        end
-
-        attribute_names
+    # To replicate the behavior in ActiveRecord#attributes,
+    # &lt;tt&gt;:except&lt;/tt&gt; takes precedence over &lt;tt&gt;:only&lt;/tt&gt;.  If &lt;tt&gt;:only&lt;/tt&gt; is not set
+    # for a N level model but is set for the N+1 level models,
+    # then because &lt;tt&gt;:except&lt;/tt&gt; is set to a default value, the second
+    # level model can have both &lt;tt&gt;:except&lt;/tt&gt; and &lt;tt&gt;:only&lt;/tt&gt; set.  So if
+    # &lt;tt&gt;:only&lt;/tt&gt; is set, always delete &lt;tt&gt;:except&lt;/tt&gt;.
+    def serializable_attribute_names
+      attribute_names = @serializable.attributes.keys.sort
+
+      if options[:only].any?
+        attribute_names &amp;= options[:only]
+      elsif options[:except].any?
+        attribute_names -= options[:except]
       end
 
-      def serializable_method_names
-        Array.wrap(options[:methods]).inject([]) do |methods, name|
-          methods &lt;&lt; name if @serializable.respond_to?(name.to_s)
-          methods
-        end
-      end
+      attribute_names
+    end
 
-      def serializable_names
-        serializable_attribute_names + serializable_method_names
+    def serializable_method_names
+      Array.wrap(options[:methods]).inject([]) do |methods, name|
+        methods &lt;&lt; name if @serializable.respond_to?(name.to_s)
+        methods
       end
+    end
 
-      def serializable_hash
-        serializable_names.inject({}) { |hash, name|
-          hash[name] = @serializable.send(name)
-          hash
-        }
-      end
+    def serializable_names
+      serializable_attribute_names + serializable_method_names
+    end
+
+    def serializable_hash
+      serializable_names.inject({}) { |hash, name|
+        hash[name] = @serializable.send(name)
+        hash
+      }
+    end
   end
 end</diff>
      <filename>activemodel/lib/active_model/serializer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,10 +16,9 @@ module ActiveModel
       class Serializer &lt; ActiveModel::Serializer
         def serializable_hash
           model = super
-          if @serializable.include_root_in_json
-            model = { @serializable.class.model_name.element =&gt; model }
-          end
-          model
+          @serializable.include_root_in_json ?
+            { @serializable.class.model_name.element =&gt; model } :
+            model
         end
 
         def serialize
@@ -27,6 +26,72 @@ module ActiveModel
         end
       end
 
+      # Returns a JSON string representing the model. Some configuration is
+      # available through +options+.
+      #
+      # The option &lt;tt&gt;ActiveRecord::Base.include_root_in_json&lt;/tt&gt; controls the
+      # top-level behavior of to_json. In a new Rails application, it is set to 
+      # &lt;tt&gt;true&lt;/tt&gt; in initializers/new_rails_defaults.rb. When it is &lt;tt&gt;true&lt;/tt&gt;,
+      # to_json will emit a single root node named after the object's type. For example:
+      #
+      #   konata = User.find(1)
+      #   ActiveRecord::Base.include_root_in_json = true
+      #   konata.to_json
+      #   # =&gt; { &quot;user&quot;: {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
+      #                   &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true} }
+      #
+      #   ActiveRecord::Base.include_root_in_json = false
+      #   konata.to_json
+      #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
+      #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true}
+      #
+      # The remainder of the examples in this section assume include_root_in_json is set to
+      # &lt;tt&gt;false&lt;/tt&gt;.
+      #
+      # Without any +options+, the returned JSON string will include all
+      # the model's attributes. For example:
+      #
+      #   konata = User.find(1)
+      #   konata.to_json
+      #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
+      #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true}
+      #
+      # The &lt;tt&gt;:only&lt;/tt&gt; and &lt;tt&gt;:except&lt;/tt&gt; options can be used to limit the attributes
+      # included, and work similar to the +attributes+ method. For example:
+      #
+      #   konata.to_json(:only =&gt; [ :id, :name ])
+      #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;}
+      #
+      #   konata.to_json(:except =&gt; [ :id, :created_at, :age ])
+      #   # =&gt; {&quot;name&quot;: &quot;Konata Izumi&quot;, &quot;awesome&quot;: true}
+      #
+      # To include any methods on the model, use &lt;tt&gt;:methods&lt;/tt&gt;.
+      #
+      #   konata.to_json(:methods =&gt; :permalink)
+      #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
+      #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true,
+      #         &quot;permalink&quot;: &quot;1-konata-izumi&quot;}
+      #
+      # To include associations, use &lt;tt&gt;:include&lt;/tt&gt;.
+      #
+      #   konata.to_json(:include =&gt; :posts)
+      #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
+      #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true,
+      #         &quot;posts&quot;: [{&quot;id&quot;: 1, &quot;author_id&quot;: 1, &quot;title&quot;: &quot;Welcome to the weblog&quot;},
+      #                   {&quot;id&quot;: 2, author_id: 1, &quot;title&quot;: &quot;So I was thinking&quot;}]}
+      #
+      # 2nd level and higher order associations work as well:
+      #
+      #   konata.to_json(:include =&gt; { :posts =&gt; {
+      #                                  :include =&gt; { :comments =&gt; {
+      #                                                :only =&gt; :body } },
+      #                                  :only =&gt; :title } })
+      #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
+      #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true,
+      #         &quot;posts&quot;: [{&quot;comments&quot;: [{&quot;body&quot;: &quot;1st post!&quot;}, {&quot;body&quot;: &quot;Second!&quot;}],
+      #                    &quot;title&quot;: &quot;Welcome to the weblog&quot;},
+      #                   {&quot;comments&quot;: [{&quot;body&quot;: &quot;Don't think too hard&quot;}],
+      #                    &quot;title&quot;: &quot;So I was thinking&quot;}]}
       def encode_json(encoder)
         Serializer.new(self, encoder.options).to_s
       end</diff>
      <filename>activemodel/lib/active_model/serializers/json.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,42 +1,9 @@
 module ActiveRecord #:nodoc:
   module Serialization
-    class Serializer #:nodoc:
-      attr_reader :options
-
-      def initialize(record, options = nil)
-        @record = record
-        @options = options ? options.dup : {}
-      end
-
-      # To replicate the behavior in ActiveRecord#attributes,
-      # &lt;tt&gt;:except&lt;/tt&gt; takes precedence over &lt;tt&gt;:only&lt;/tt&gt;.  If &lt;tt&gt;:only&lt;/tt&gt; is not set
-      # for a N level model but is set for the N+1 level models,
-      # then because &lt;tt&gt;:except&lt;/tt&gt; is set to a default value, the second
-      # level model can have both &lt;tt&gt;:except&lt;/tt&gt; and &lt;tt&gt;:only&lt;/tt&gt; set.  So if
-      # &lt;tt&gt;:only&lt;/tt&gt; is set, always delete &lt;tt&gt;:except&lt;/tt&gt;.
-      def serializable_attribute_names
-        attribute_names = @record.attribute_names
-
-        if options[:only]
-          options.delete(:except)
-          attribute_names = attribute_names &amp; Array.wrap(options[:only]).collect { |n| n.to_s }
-        else
-          options[:except] = Array.wrap(options[:except]) | Array.wrap(@record.class.inheritance_column)
-          attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
-        end
-
-        attribute_names
-      end
-
-      def serializable_method_names
-        Array.wrap(options[:methods]).inject([]) do |method_attributes, name|
-          method_attributes &lt;&lt; name if @record.respond_to?(name.to_s)
-          method_attributes
-        end
-      end
-
-      def serializable_names
-        serializable_attribute_names + serializable_method_names
+    module RecordSerializer #:nodoc:
+      def initialize(*args)
+        super
+        options[:except] |= Array.wrap(@serializable.class.inheritance_column)
       end
 
       # Add associations specified via the &lt;tt&gt;:includes&lt;/tt&gt; option.
@@ -53,11 +20,11 @@ module ActiveRecord #:nodoc:
           associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
 
           for association in associations
-            records = case @record.class.reflect_on_association(association).macro
+            records = case @serializable.class.reflect_on_association(association).macro
             when :has_many, :has_and_belongs_to_many
-              @record.send(association).to_a
+              @serializable.send(association).to_a
             when :has_one, :belongs_to
-              @record.send(association)
+              @serializable.send(association)
             end
 
             unless records.nil?
@@ -71,28 +38,19 @@ module ActiveRecord #:nodoc:
         end
       end
 
-      def serializable_record
-        record = {}
-        serializable_names.each { |name| record[name] = @record.send(name) }
+      def serializable_hash
+        hash = super
 
         add_includes do |association, records, opts|
-          record[association] =
+          hash[association] =
             if records.is_a?(Enumerable)
-              records.collect { |r| self.class.new(r, opts).serializable_record }
+              records.collect { |r| self.class.new(r, opts).serializable_hash }
             else
-              self.class.new(records, opts).serializable_record
+              self.class.new(records, opts).serializable_hash
             end
         end
 
-        record
-      end
-
-      def serialize
-        # overwrite to implement
-      end
-
-      def to_s(&amp;block)
-        serialize(&amp;block)
+        hash
       end
     end
   end</diff>
      <filename>activerecord/lib/active_record/serialization.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,91 +1,14 @@
-require 'active_support/json'
-require 'active_model/naming'
-
 module ActiveRecord #:nodoc:
   module Serialization
     extend ActiveSupport::Concern
+    include ActiveModel::Serializers::JSON
 
-    included do
-      cattr_accessor :include_root_in_json, :instance_writer =&gt; false
+    class JSONSerializer &lt; ActiveModel::Serializers::JSON::Serializer
+      include Serialization::RecordSerializer
     end
 
-    # Returns a JSON string representing the model. Some configuration is
-    # available through +options+.
-    #
-    # The option &lt;tt&gt;ActiveRecord::Base.include_root_in_json&lt;/tt&gt; controls the
-    # top-level behavior of to_json. In a new Rails application, it is set to 
-    # &lt;tt&gt;true&lt;/tt&gt; in initializers/new_rails_defaults.rb. When it is &lt;tt&gt;true&lt;/tt&gt;,
-    # to_json will emit a single root node named after the object's type. For example:
-    #
-    #   konata = User.find(1)
-    #   ActiveRecord::Base.include_root_in_json = true
-    #   konata.to_json
-    #   # =&gt; { &quot;user&quot;: {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
-    #                   &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true} }
-    #
-    #   ActiveRecord::Base.include_root_in_json = false
-    #   konata.to_json
-    #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
-    #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true}
-    #
-    # The remainder of the examples in this section assume include_root_in_json is set to
-    # &lt;tt&gt;false&lt;/tt&gt;.
-    #
-    # Without any +options+, the returned JSON string will include all
-    # the model's attributes. For example:
-    #
-    #   konata = User.find(1)
-    #   konata.to_json
-    #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
-    #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true}
-    #
-    # The &lt;tt&gt;:only&lt;/tt&gt; and &lt;tt&gt;:except&lt;/tt&gt; options can be used to limit the attributes
-    # included, and work similar to the +attributes+ method. For example:
-    #
-    #   konata.to_json(:only =&gt; [ :id, :name ])
-    #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;}
-    #
-    #   konata.to_json(:except =&gt; [ :id, :created_at, :age ])
-    #   # =&gt; {&quot;name&quot;: &quot;Konata Izumi&quot;, &quot;awesome&quot;: true}
-    #
-    # To include any methods on the model, use &lt;tt&gt;:methods&lt;/tt&gt;.
-    #
-    #   konata.to_json(:methods =&gt; :permalink)
-    #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
-    #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true,
-    #         &quot;permalink&quot;: &quot;1-konata-izumi&quot;}
-    #
-    # To include associations, use &lt;tt&gt;:include&lt;/tt&gt;.
-    #
-    #   konata.to_json(:include =&gt; :posts)
-    #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
-    #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true,
-    #         &quot;posts&quot;: [{&quot;id&quot;: 1, &quot;author_id&quot;: 1, &quot;title&quot;: &quot;Welcome to the weblog&quot;},
-    #                   {&quot;id&quot;: 2, author_id: 1, &quot;title&quot;: &quot;So I was thinking&quot;}]}
-    #
-    # 2nd level and higher order associations work as well:
-    #
-    #   konata.to_json(:include =&gt; { :posts =&gt; {
-    #                                  :include =&gt; { :comments =&gt; {
-    #                                                :only =&gt; :body } },
-    #                                  :only =&gt; :title } })
-    #   # =&gt; {&quot;id&quot;: 1, &quot;name&quot;: &quot;Konata Izumi&quot;, &quot;age&quot;: 16,
-    #         &quot;created_at&quot;: &quot;2006/08/01&quot;, &quot;awesome&quot;: true,
-    #         &quot;posts&quot;: [{&quot;comments&quot;: [{&quot;body&quot;: &quot;1st post!&quot;}, {&quot;body&quot;: &quot;Second!&quot;}],
-    #                    &quot;title&quot;: &quot;Welcome to the weblog&quot;},
-    #                   {&quot;comments&quot;: [{&quot;body&quot;: &quot;Don't think too hard&quot;}],
-    #                    &quot;title&quot;: &quot;So I was thinking&quot;}]}
     def encode_json(encoder)
-      hash = Serializer.new(self, encoder.options).serializable_record
-      hash = { self.class.model_name.element =&gt; hash } if include_root_in_json
-      ActiveSupport::JSON.encode(hash)
-    end
-
-    def as_json(options = nil) self end #:nodoc:
-
-    def from_json(json)
-      self.attributes = ActiveSupport::JSON.decode(json)
-      self
+      JSONSerializer.new(self, encoder.options).to_s
     end
   end
 end</diff>
      <filename>activerecord/lib/active_record/serializers/json_serializer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -164,7 +164,9 @@ module ActiveRecord #:nodoc:
     end
   end
 
-  class XmlSerializer &lt; ActiveRecord::Serialization::Serializer #:nodoc:
+  class XmlSerializer &lt; ActiveModel::Serializer #:nodoc:
+    include Serialization::RecordSerializer
+
     def builder
       @builder ||= begin
         require 'builder' unless defined? ::Builder
@@ -181,7 +183,7 @@ module ActiveRecord #:nodoc:
     end
 
     def root
-      root = (options[:root] || @record.class.to_s.underscore).to_s
+      root = (options[:root] || @serializable.class.to_s.underscore).to_s
       reformat_name(root)
     end
 
@@ -199,12 +201,12 @@ module ActiveRecord #:nodoc:
     end
 
     def serializable_attributes
-      serializable_attribute_names.collect { |name| Attribute.new(name, @record) }
+      serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) }
     end
 
     def serializable_method_attributes
       Array(options[:methods]).inject([]) do |method_attributes, name|
-        method_attributes &lt;&lt; MethodAttribute.new(name.to_s, @record) if @record.respond_to?(name.to_s)
+        method_attributes &lt;&lt; MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
         method_attributes
       end
     end
@@ -254,7 +256,7 @@ module ActiveRecord #:nodoc:
           end
         end
       else
-        if record = @record.send(association)
+        if record = @serializable.send(association)
           record.to_xml(opts.merge(:root =&gt; association))
         end
       end</diff>
      <filename>activerecord/lib/active_record/serializers/xml_serializer.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d2b78b3594b9cc9870e6a6ebfeb2e56d00e6ddb8</id>
    </parent>
  </parents>
  <author>
    <name>Joshua Peek</name>
    <email>josh@joshpeek.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/783db25e0c640c1588732967a87d65c10fddc08e</url>
  <id>783db25e0c640c1588732967a87d65c10fddc08e</id>
  <committed-date>2009-07-03T21:12:42-07:00</committed-date>
  <authored-date>2009-07-03T21:12:42-07:00</authored-date>
  <message>Integrate AMo JSON serializer into AR</message>
  <tree>c9fbcd586a23aa79c77f1017a1f9bc6104c20bcd</tree>
  <committer>
    <name>Joshua Peek</name>
    <email>josh@joshpeek.com</email>
  </committer>
</commit>
