aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-02-01 09:34:21 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2011-02-01 14:25:46 -0800
commit3cc2b77dc1cb4c1e5cfac68c7828e35a27415e0d (patch)
treea4c0ff4344492bfaed687e1321e7bb8511933e97 /activerecord
parent0171de00b7a21b9f2866f600fe2aca3152608e33 (diff)
downloadrails-3cc2b77dc1cb4c1e5cfac68c7828e35a27415e0d.tar.gz
rails-3cc2b77dc1cb4c1e5cfac68c7828e35a27415e0d.tar.bz2
rails-3cc2b77dc1cb4c1e5cfac68c7828e35a27415e0d.zip
adding a YAML Column coder for YAML serialization to db columns
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record.rb4
-rw-r--r--activerecord/lib/active_record/coders/yaml_column.rb34
-rw-r--r--activerecord/test/cases/coders/yaml_column_test.rb45
3 files changed, 83 insertions, 0 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index c80bce2849..5afb97803e 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -81,6 +81,10 @@ module ActiveRecord
autoload :Validations
end
+ module Coders
+ autoload :YAMLColumn, 'active_record/coders/yaml_column'
+ end
+
module AttributeMethods
extend ActiveSupport::Autoload
diff --git a/activerecord/lib/active_record/coders/yaml_column.rb b/activerecord/lib/active_record/coders/yaml_column.rb
new file mode 100644
index 0000000000..9b0df119ef
--- /dev/null
+++ b/activerecord/lib/active_record/coders/yaml_column.rb
@@ -0,0 +1,34 @@
+module ActiveRecord
+ # :stopdoc:
+ module Coders
+ class YAMLColumn
+ RESCUE_ERRORS = [ ArgumentError ]
+
+ if defined?(Psych) && defined?(Psych::SyntaxError)
+ RESCUE_ERRORS << Psych::SyntaxError
+ end
+
+ attr_accessor :object_class
+
+ def initialize(object_class = Object)
+ @object_class = object_class
+ end
+
+ def load(yaml)
+ return yaml unless yaml.is_a?(String) && yaml =~ /^---/
+ begin
+ obj = YAML::load(yaml)
+
+ unless obj.is_a?(object_class) || obj.nil?
+ raise SerializationTypeMismatch,
+ "Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
+ end
+
+ rescue *RESCUE_ERRORS
+ yaml
+ end
+ end
+ end
+ end
+ # :startdoc
+end
diff --git a/activerecord/test/cases/coders/yaml_column_test.rb b/activerecord/test/cases/coders/yaml_column_test.rb
new file mode 100644
index 0000000000..f85f11b57f
--- /dev/null
+++ b/activerecord/test/cases/coders/yaml_column_test.rb
@@ -0,0 +1,45 @@
+require "cases/helper"
+
+module ActiveRecord
+ module Coders
+ class YAMLColumnTest < ActiveRecord::TestCase
+ def test_initialize_takes_class
+ coder = YAMLColumn.new(Object)
+ assert_equal Object, coder.object_class
+ end
+
+ def test_type_mismatch_on_different_classes
+ coder = YAMLColumn.new(Array)
+ assert_raises(SerializationTypeMismatch) do
+ coder.load "--- foo"
+ end
+ end
+
+ def test_nil_is_ok
+ coder = YAMLColumn.new
+ assert_nil coder.load "--- "
+ end
+
+ def test_nil_is_ok_with_different_class
+ coder = YAMLColumn.new SerializationTypeMismatch
+ assert_nil coder.load "--- "
+ end
+
+ def test_returns_string_unless_starts_with_dash
+ coder = YAMLColumn.new
+ assert_equal 'foo', coder.load("foo")
+ end
+
+ def test_load_handles_other_classes
+ coder = YAMLColumn.new
+ assert_equal [], coder.load([])
+ end
+
+ def test_load_swallows_yaml_exceptions
+ coder = YAMLColumn.new
+ bad_yaml = '--- {'
+ assert_equal bad_yaml, coder.load(bad_yaml)
+ end
+ end
+ end
+end