#950 ✓resolved
Ashley Moran

Resource#dirty? does not consider associations

Reported by Ashley Moran | July 6th, 2009 @ 06:30 AM | in 0.10.0

This came out of #940. We had an object graph like this:

A → B ← C

B has n A, and B has n C.

If the graph is saved with an A and B, but no Cs, then you add a C to B and save A, C never gets saved (even with the fully recursive save proposed in #940), because B does not consider itself dirty. I believe that associated collections should count towards #dirty? the same way properties do.

Proof of the behaviour follows, courtesy of the continuingly elusive and mysterious mrship:

require 'rubygems'
 
USE_DM_0_9 = false
 
if USE_DM_0_9
  DM_GEMS_VERSION   = "0.9.11"
  DO_GEMS_VERSION   = "0.9.12"
else
  DM_GEMS_VERSION   = "0.10.0"
  DO_GEMS_VERSION   = "0.10.0"
end
 
gem "data_objects",    DO_GEMS_VERSION
gem "do_postgres",     DO_GEMS_VERSION # If using another database, replace this
gem "dm-core",         DM_GEMS_VERSION         
gem "dm-aggregates",   DM_GEMS_VERSION   
gem "dm-migrations",   DM_GEMS_VERSION   
gem "dm-timestamps",   DM_GEMS_VERSION   
gem "dm-types",        DM_GEMS_VERSION        
gem "dm-validations",  DM_GEMS_VERSION  
gem "dm-serializer",   DM_GEMS_VERSION  
 
require "data_objects"
require "do_postgres"
require "dm-core"
require "dm-aggregates"
require "dm-migrations"
require "dm-timestamps"
require "dm-types"
require "dm-validations"
require "dm-serializer"

require 'spec'
 
SQLITE_FILE = File.join(`pwd`.chomp, "test.db")
 
DataMapper.setup(:default, "sqlite3:#{SQLITE_FILE}")
DataMapper.setup(:reloaded, "sqlite3:#{SQLITE_FILE}")
 
class Parent
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :nullable => false
  
  validates_is_unique :name
  
  has n, :kids, :order => [:name]
  
end
 
class Kid
  include DataMapper::Resource
  property :id, Serial
  property :name, String
  
  belongs_to :parent, :model => "Parent", :child_key => [:parent_id]  
  
  validates_is_unique :name, :scope => :parent
end
 
module IdentityMapHelper
  def reload(object)
    object.class.get(object.id)
  end
  
  def with_db_reconnect(&blk)
    original_repository = DataMapper::Repository.context.pop
    repository(:reloaded, &blk)
    DataMapper::Repository.context << original_repository
  end
end
 
Spec::Runner.configure do |config|
  include IdentityMapHelper
  
  config.before(:each) do
    Parent.auto_migrate!
    Kid.auto_migrate!
  end
  
  config.before(:each) do    
    DataMapper::Repository.context << repository(:default)
  end
  
  config.after(:each) do
    DataMapper::Repository.context.pop
  end
end
 
describe Parent do
  before(:each) do
    @parent = Parent.new(:name => "Homer")
  end
  
  it "should be dirty if a child is added" do
    @parent.save
    @parent.kids.new(:name => "Bart")
    @parent.should be_dirty
  end
end

Comments and changes to this ticket

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.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

People watching this ticket

Referenced by

Pages