Skip to content

Instantly share code, notes, and snippets.

@brundage
Created October 10, 2012 18:35
Show Gist options
  • Save brundage/3867551 to your computer and use it in GitHub Desktop.
Save brundage/3867551 to your computer and use it in GitHub Desktop.
Nil Returning ActiveRecord::Coders::YAMLColumn
require 'active_record/coders/yaml_column'
require 'active_support'
require 'yaml'
# This module defines an YAMLColumn coder that returns
# nil instead of a blank object. Useful when the class you are serializing
# to/from does not allow uninitialized objects (such as a unit measurement)
#
# See more: http://blog.deanbrundage.com/2012/10/rails-serialization-of-nil-values/
#
module NilReturningCoder
extend ActiveSupport::Concern
module ClassMethods
def dump(obj)
Coder.new.dump(obj)
end
def load(yaml)
Coder.new.load(yaml)
end
end
private
class Coder < ActiveRecord::Coders::YAMLColumn
def dump(obj)
return if obj.nil?
super
end
def load(yaml)
return if yaml.nil?
super
end
end
end
Blark = Struct.new(:attr) do
include NilReturningCoder
end
describe NilReturningCoder do
let(:klass) { Blark }
let(:object) { klass.new }
let(:coder) { NilReturningCoder::Coder.new }
shared_examples_for 'a dumper' do
it 'returns nil when given nil' do
dumper.dump(nil).should be_nil
end
it 'returns yaml when given something' do
dumper.dump(object).should eq object.to_yaml
end
end
shared_examples_for 'a loader' do
it 'returns nil when given nil' do
loader.load(nil).should be_nil
end
it 'returns the object when given yaml' do
loader.load(object.to_yaml).should eq object
end
end
describe :ClassMethods do
[:dump, :load].each do |meth|
it "mixes in #{meth}" do
klass.should respond_to(meth)
end
end
it_behaves_like 'a dumper' do
let(:dumper) { klass }
end
it_behaves_like 'a loader' do
let(:loader) { klass }
end
end
describe :Coder do
it_behaves_like 'a dumper' do
let(:dumper) { coder }
end
it_behaves_like 'a loader' do
let(:loader) { coder }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment