Created
October 10, 2012 18:35
-
-
Save brundage/3867551 to your computer and use it in GitHub Desktop.
Nil Returning ActiveRecord::Coders::YAMLColumn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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