-
Type: Bug
-
Resolution: Unresolved
-
Priority: Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
When a type with a nontrivial `mongoize` implementation is stored in a Mongoid document as a value in a field of type Hash or Array, the value gets mongoized (which is a transformation) and subsequent attribute reads/accesses return the mongoized value which is different from the value that was provided to the model to begin with.
Example:
class Mop include Mongoid::Document field :f, type: Hash field :g, type: Array end irb(main):071:0> a=Mop.new(f: {hello: 1..2}) => #<Mop _id: 61dfff7da15d5d6a60e99471, int_field: nil, array_field: nil, date_field: nil, tim... irb(main):072:0> a.f[:hello] => {"min"=>1, "max"=>2} irb(main):073:0> a.f => {:hello=>{"min"=>1, "max"=>2}} irb(main):080:0> a=Mop.new(g: [hello: 1..2]) => #<Mop _id: 61dfffa6a15d5d6a60e99472, int_field: nil, array_field: nil, date_field: nil, tim... irb(main):081:0> a.g => [{:hello=>{"min"=>1, "max"=>2}}]
Here, Range has non-trivial mongoization behavior, and once the f or g attributes are written, subsequent reads produce the range as a hash which is presumably how Mongoid would write it to the database.
This behavior becomes more problematic when BigDecimal values are involved, as those would be converted to BSON::Decimal128 which then users will struggle using.
Possible solution: add recursive demongoize methods to Hash and Array.
A little further explanation on this possible solution. All values are mongoized on assignment and insertion into the attributes hash. However, the difference between those values and those nested in a hash or array is, these values are demongoized on reading them. So for example if Mop was:
class Mop include Mongoid::Document field :f, type: Hash field :g, type: Array field :h, type: Range end a=Mop.new(h:1..2) a.h # => 1..2 a.attributes['h'] # => {"min"=>1, "max"=>2}
As you can see, the value for h is stored in its mongoized form and then demongoized when it's retrieved. If we can demongoize hashes recursively then we can get a similar functionality.
- is related to
-
MONGOID-2951 Attributes of container types are not persisted when mutated
- Backlog