Skip to content

Commit

Permalink
Allow serializable fields to be of type hash. Fixes #1311.
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Oct 6, 2011
1 parent 46a3cb7 commit ddafe0e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/mongoid/fields.rb
Expand Up @@ -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)
Expand Down
21 changes: 14 additions & 7 deletions lib/mongoid/fields/serializable.rb
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions spec/app/models/my_hash.rb
@@ -0,0 +1,3 @@
class MyHash < ::Hash
include Mongoid::Fields::Serializable
end
29 changes: 29 additions & 0 deletions 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

0 comments on commit ddafe0e

Please sign in to comment.