diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2007-09-20 23:22:30 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2007-09-20 23:22:30 +0000 |
commit | e86d1cd621ca62af6f71b04032b1e07a66c06bb6 (patch) | |
tree | 638a89da26f9066cc333f0ce059c3ce551a97d24 /activerecord/lib | |
parent | dc399b96c84bc66b7c20e92fb40e9ed00daf99c2 (diff) | |
download | rails-e86d1cd621ca62af6f71b04032b1e07a66c06bb6.tar.gz rails-e86d1cd621ca62af6f71b04032b1e07a66c06bb6.tar.bz2 rails-e86d1cd621ca62af6f71b04032b1e07a66c06bb6.zip |
Added ActiveRecord::Base#to_json/from_json (currently does not support :include like to_xml) [DHH]. Added ActiveRecord::Base#from_xml [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7519 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib')
-rwxr-xr-x | activerecord/lib/active_record.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/association_collection.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/active_record/serialization.rb | 59 | ||||
-rw-r--r-- | activerecord/lib/active_record/serializers/json_serializer.rb | 18 | ||||
-rw-r--r-- | activerecord/lib/active_record/serializers/xml_serializer.rb (renamed from activerecord/lib/active_record/xml_serialization.rb) | 29 |
5 files changed, 89 insertions, 24 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index f1585d640b..73f5229753 100755 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -49,7 +49,7 @@ require 'active_record/locking/pessimistic' require 'active_record/migration' require 'active_record/schema' require 'active_record/calculations' -require 'active_record/xml_serialization' +require 'active_record/serialization' require 'active_record/attribute_methods' ActiveRecord::Base.class_eval do @@ -65,7 +65,7 @@ ActiveRecord::Base.class_eval do include ActiveRecord::Transactions include ActiveRecord::Reflection include ActiveRecord::Calculations - include ActiveRecord::XmlSerialization + include ActiveRecord::Serialization include ActiveRecord::AttributeMethods end diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 460f410cf0..66ee712d7d 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -158,6 +158,7 @@ module ActiveRecord end end + protected def method_missing(method, *args, &block) if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) @@ -218,4 +219,4 @@ module ActiveRecord end end -end +end
\ No newline at end of file diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb new file mode 100644 index 0000000000..f10d1b3b7e --- /dev/null +++ b/activerecord/lib/active_record/serialization.rb @@ -0,0 +1,59 @@ +module ActiveRecord #:nodoc: + module Serialization + class Serializer #:nodoc: + attr_reader :options + + def initialize(record, options = {}) + @record, @options = record, options.dup + end + + # To replicate the behavior in ActiveRecord#attributes, + # :except takes precedence over :only. If :only is not set + # for a N level model but is set for the N+1 level models, + # then because :except is set to a default value, the second + # level model can have both :except and :only set. So if + # :only is set, always delete :except. + def serializable_attribute_names + attribute_names = @record.attribute_names + + if options[:only] + options.delete(:except) + attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s } + else + options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column) + attribute_names = attribute_names - options[:except].collect { |n| n.to_s } + end + + attribute_names + end + + def serializable_method_names + Array(options[:methods]).inject([]) do |method_attributes, name| + method_attributes << :name if @record.respond_to?(name.to_s) + method_attributes + end + end + + def serializable_names + serializable_attribute_names + serializable_method_names + end + + def serializable_record + returning(serializable_record = {}) do + serializable_names.each { |name| serializable_record[name] = @record.send(name) } + end + end + + def serialize + # overwrite to implement + end + + def to_s(&block) + serialize(&block) + end + end + end +end + +require 'active_record/serializers/xml_serializer' +require 'active_record/serializers/json_serializer'
\ No newline at end of file diff --git a/activerecord/lib/active_record/serializers/json_serializer.rb b/activerecord/lib/active_record/serializers/json_serializer.rb new file mode 100644 index 0000000000..97025ae4d3 --- /dev/null +++ b/activerecord/lib/active_record/serializers/json_serializer.rb @@ -0,0 +1,18 @@ +module ActiveRecord #:nodoc: + module Serialization + def to_json(options = {}, &block) + JsonSerializer.new(self, options).to_s + end + + def from_json(json) + self.attributes = ActiveSupport::JSON.decode(json) + self + end + + class JsonSerializer < ActiveRecord::Serialization::Serializer #:nodoc: + def serialize + serializable_record.to_json + end + end + end +end diff --git a/activerecord/lib/active_record/xml_serialization.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index e32565745e..1e4101f183 100644 --- a/activerecord/lib/active_record/xml_serialization.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -1,5 +1,5 @@ module ActiveRecord #:nodoc: - module XmlSerialization + module Serialization # Builds an XML document to represent the model. Some configuration is # availble through +options+, however more complicated cases should use # override ActiveRecord's to_xml. @@ -124,15 +124,14 @@ module ActiveRecord #:nodoc: serializer = XmlSerializer.new(self, options) block_given? ? serializer.to_s(&block) : serializer.to_s end - end - class XmlSerializer #:nodoc: - attr_reader :options - - def initialize(record, options = {}) - @record, @options = record, options.dup + def from_xml(xml) + self.attributes = Hash.from_xml(xml).values.first + self end - + end + + class XmlSerializer < ActiveRecord::Serialization::Serializer #:nodoc: def builder @builder ||= begin options[:indent] ||= 2 @@ -164,17 +163,7 @@ module ActiveRecord #:nodoc: # level model can have both :except and :only set. So if # :only is set, always delete :except. def serializable_attributes - attribute_names = @record.attribute_names - - if options[:only] - options.delete(:except) - attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s } - else - options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column) - attribute_names = attribute_names - options[:except].collect { |n| n.to_s } - end - - attribute_names.collect { |name| Attribute.new(name, @record) } + serializable_attribute_names.collect { |name| Attribute.new(name, @record) } end def serializable_method_attributes @@ -265,8 +254,6 @@ module ActiveRecord #:nodoc: yield builder if block_given? end end - - alias_method :to_s, :serialize class Attribute #:nodoc: attr_reader :name, :value, :type |