aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2007-09-20 23:22:30 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2007-09-20 23:22:30 +0000
commite86d1cd621ca62af6f71b04032b1e07a66c06bb6 (patch)
tree638a89da26f9066cc333f0ce059c3ce551a97d24 /activerecord/lib
parentdc399b96c84bc66b7c20e92fb40e9ed00daf99c2 (diff)
downloadrails-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-xactiverecord/lib/active_record.rb4
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb3
-rw-r--r--activerecord/lib/active_record/serialization.rb59
-rw-r--r--activerecord/lib/active_record/serializers/json_serializer.rb18
-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