From ddafe0ea9688228b3bc3b779afa7460fd62dc351 Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Tue, 4 Oct 2011 16:04:56 +0200 Subject: [PATCH] Allow serializable fields to be of type hash. Fixes #1311. --- lib/mongoid/fields.rb | 2 +- lib/mongoid/fields/serializable.rb | 21 +++++++++----- spec/app/models/my_hash.rb | 3 ++ spec/unit/mongoid/fields/serializable_spec.rb | 29 +++++++++++++++++++ 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 spec/app/models/my_hash.rb create mode 100644 spec/unit/mongoid/fields/serializable_spec.rb diff --git a/lib/mongoid/fields.rb b/lib/mongoid/fields.rb index 2187689cad..8b62b09e17 100644 --- a/lib/mongoid/fields.rb +++ b/lib/mongoid/fields.rb @@ -231,7 +231,7 @@ def add_field(name, options = {}) type = options[:localize] ? Fields::Serializable::Localized : options[:type] Mappings.for(type, options[:identity]).instantiate(name, options).tap do |field| fields[name] = field - defaults << name unless field.default.nil? + defaults << name unless field.default_val.nil? create_accessors(name, meth, options) process_options(field) define_attribute_method(name) diff --git a/lib/mongoid/fields/serializable.rb b/lib/mongoid/fields/serializable.rb index 7961a59fd0..c3849b69f4 100644 --- a/lib/mongoid/fields/serializable.rb +++ b/lib/mongoid/fields/serializable.rb @@ -25,8 +25,15 @@ module Fields #:nodoc: module Serializable extend ActiveSupport::Concern + included do + # @todo: Durran: Pull out in 3.0.0 + unless method_defined?(:default) + alias :default :default_val + end + end + # Set readers for the instance variables. - attr_accessor :default, :label, :localize, :name, :options + attr_accessor :default_val, :label, :localize, :name, :options # When reading the field do we need to cast the value? This holds true when # times are stored or for big decimals which are stored as strings. @@ -82,10 +89,10 @@ def deserialize(object); object; end # # @since 2.1.8 def eval_default(doc) - if default.respond_to?(:call) - serialize(doc.instance_exec(&default)) + if default_val.respond_to?(:call) + serialize(doc.instance_exec(&default_val)) else - serialize(default.duplicable? ? default.dup : default) + serialize(default_val.duplicable? ? default_val.dup : default_val) end end @@ -182,9 +189,9 @@ def instantiate(name, options = {}) field.options = options field.label = options[:label] field.localize = options[:localize] - field.default = options[:default] - unless field.default - field.default = {} if field.localized? + field.default_val = options[:default] + unless field.default_val + field.default_val = {} if field.localized? end end end diff --git a/spec/app/models/my_hash.rb b/spec/app/models/my_hash.rb new file mode 100644 index 0000000000..846c9a3c49 --- /dev/null +++ b/spec/app/models/my_hash.rb @@ -0,0 +1,3 @@ +class MyHash < ::Hash + include Mongoid::Fields::Serializable +end diff --git a/spec/unit/mongoid/fields/serializable_spec.rb b/spec/unit/mongoid/fields/serializable_spec.rb new file mode 100644 index 0000000000..44b405cea7 --- /dev/null +++ b/spec/unit/mongoid/fields/serializable_spec.rb @@ -0,0 +1,29 @@ +require "spec_helper" + +describe Mongoid::Fields::Serializable do + + context "when included in a hash" do + + let(:hash) do + MyHash.new + end + + context "when setting a value" do + + before do + hash[:key] = "value" + end + + it "allows normal hash access" do + hash[:key].should eq("value") + end + end + + context "when getting a non existant value" do + + it "returns nil" do + hash[:key].should be_nil + end + end + end +end