#955 ✓resolved
Ashley Moran

Swapping elements in an association collection sets parent to nil

Reported by Ashley Moran | July 6th, 2009 @ 04:35 PM | in 0.10.0

Another spec courtesy of the prolific 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 "do_sqlite3",     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 "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 Farm
  include DataMapper::Resource

  property :id, Serial
  
  has n, :cows, :order => [:cow_id]
end
 
class Cow
  include DataMapper::Resource

  property :id, Serial
  property :cow_id, Integer
  property :name, String

  # Comment out the following line to make the spec pass
  validates_is_unique :name, :scope => [:farm]
  
  belongs_to :farm
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
    Farm.auto_migrate!
    Cow.auto_migrate!
  end
  
  config.before(:each) do    
    DataMapper::Repository.context << repository(:default)
  end
  
  config.after(:each) do
    DataMapper::Repository.context.pop
  end
end
 
describe "Swapping elements in a collection using #[] accessor" do
  before(:each) do
    @bluebell_farm = Farm.new
    @cow_1 = Cow.new(:cow_id => 1, :name => "Daisy")
    @cow_2 = Cow.new(:cow_id => 2, :name => "Florence")
    @cow_4 = Cow.new(:cow_id => 3, :name => "Juicysteak")
    @cow_3 = Cow.new(:cow_id => 4, :name => "Tastyburger")
    
    @bluebell_farm.cows << @cow_1 << @cow_2 << @cow_3 << @cow_4
  end
  
  it "should let you swap elements and not lose the association" do
    @bluebell_farm.cows[0].farm.should_not be_nil
    @bluebell_farm.cows[1].farm.should_not be_nil
    @bluebell_farm.cows[0], @bluebell_farm.cows[1] = @bluebell_farm.cows[1], @bluebell_farm.cows[0]
    @bluebell_farm.cows[0].farm.should_not be_nil
    @bluebell_farm.cows[1].farm.should_not be_nil
  end
  
  it "should let you swap elements and not lose the association without having to save" do
    @bluebell_farm.cows[0].farm.should_not be_nil
    @bluebell_farm.cows[1].farm.should_not be_nil
    @bluebell_farm.cows[0], @bluebell_farm.cows[1] = @bluebell_farm.cows[1], @bluebell_farm.cows[0]
    @bluebell_farm.save
    @bluebell_farm.cows[0].farm.should_not be_nil
    @bluebell_farm.cows[1].farm.should_not be_nil
  end
end

I have not given any thought to why the first example fails (after the switch), but it looks clearly wrong to me. Any thoughts?

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