From 3cc2b77dc1cb4c1e5cfac68c7828e35a27415e0d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 1 Feb 2011 09:34:21 -0800 Subject: adding a YAML Column coder for YAML serialization to db columns --- activerecord/lib/active_record.rb | 4 ++ .../lib/active_record/coders/yaml_column.rb | 34 ++++++++++++++++ activerecord/test/cases/coders/yaml_column_test.rb | 45 ++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 activerecord/lib/active_record/coders/yaml_column.rb create mode 100644 activerecord/test/cases/coders/yaml_column_test.rb (limited to 'activerecord') 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 -- cgit v1.2.3