
YAML data type sometimes badly tracks changes
Reported by gondar | September 25th, 2009 @ 08:13 AM
When I am using YAML data type in data_mapper some operations on
Arrays and Hashes are not seen by data mapper and not saved into
database.
Workaround is to use only assign function on Arrays and Hashes
saved to database as YAML.
Script showing problem:
require 'rubygems'
require 'dm-core'
require 'dm-types'
# An in-memory Sqlite3 connection: DataMapper.setup(:default, 'sqlite3::memory:')
class Category
include DataMapper::Resource property :id, Serial property :name,
String property :links, DataMapper::Types::Yaml
end
DataMapper.auto_migrate!
DataMapper::Logger.new(STDOUT, :debug)
print "Creating new category..."
c = Category.new
puts "[OK]"
c.name = 'Empty'
c.links = []
c.save
puts "New category links look like #{c.links.to_yaml}"
empty_id = c.id
c.links << {:a=>12}
c.save
puts "Changed category links set to look like
#{c.links.to_yaml}"
puts "After rereading category links look like
#{Category.get(empty_id).links.to_yaml}"
if Category.get(empty_id).links.size == 0 then
puts "There is problem" else
puts "Everything is fine" end
Problem appeared both in trunk and in current gem from repository.
Comments and changes to this ticket
-
gondar September 26th, 2009 @ 02:40 AM
- Title changed from YAML data type doesn't sometimes badly tracks changes to YAML data type sometimes badly tracks changes
-
Dan Kubb (dkubb) October 6th, 2009 @ 12:48 PM
- State changed from new to suggestion
- Tag changed from 0.9.11, dm-types, yaml to dm-types, yaml
Currently DataMapper only tracks changes caused by calling the mutator methods, not changes using the reference to the value internally.
So for example, if you have a String, and you set the user.name using user.name = "gondar", and then later you use user.name << "other" to append to the String, DataMapper isn't going to notice the change since you modified the value that it has a reference to.
DataMapper used to track this sort of change, but it incurred a large overhead and was needlessly complex. I removed it until we could figure out a better approach.
I suppose it may be possible if we take a snapshot of the object attributes' Object#hash values when it is loaded, and then compare those when it comes time to save the object. I'm not yet sure what sort of overhead this will have, but it may be worth looking into later.
For now I am going to mark this as a "suggestion" and we will revisit it prior to 1.0
-
blavender (at gmail) January 20th, 2010 @ 08:55 AM
I wish this ticket were higher on google, but here's a workaround for anyone else who, like me, finds this type not very useful without this feature. Unfortunately, it will always save the YAML property if it has been loaded at all.
before :save, :dump_yaml def dump_yaml self.yaml_prop = YAML.dump(self.yaml_prop) if attribute_loaded? :yaml_prop end
-
blavender (at gmail) January 20th, 2010 @ 09:32 AM
I added a pending spec for this and sent a pull request, see http://github.com/bhuga/dm-more/commit/e09a0579290a7036ee19f4d9f8c173ebad2a9654
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »