The examples below demonstrate this bug. What is happening is that a Child (except when #953 strikes) considers itself invalid when it has a nil parent_id. I believe that when a parent object is associated to the child but new, the valid? check on the child should either: check that there is a parent associated, or, check a parent is associated and also that it is valid.
In fact, I am starting to think that the definition of validity should never rely on the ID, because this should always be obtainable when a valid parent is saved.
Note that this line of thought taken to its logical conclusion means that checking if a child object is valid would involve checking the validity of the entire object graph. (The same issues as found in #940 would apply. This may also extend to the discussion at http://groups.google.com/group/datamapper/t/a80a60b7a3663ef5 about repository-wide operations.)
ruby
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_sqlite3", DO_GEMS_VERSION # If using another database, replace this
gem "dm-core", DM_GEMS_VERSION
gem "dm-types", DM_GEMS_VERSION
gem "dm-validations", 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 Parent
include DataMapper::Resource
property :id, Serial
has n, :children
end
class Child
include DataMapper::Resource
property :id, Serial
belongs_to :parent
has n, :pets
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
DataMapper.auto_migrate!
end
config.before(:each) do
DataMapper::Repository.context << repository(:default)
end
config.after(:each) do
DataMapper::Repository.context.pop
end
end
describe "Child with unsaved parent" do
before(:each) do
= Child.new
= Parent.new
.children <<
end
it "should define a new child with an assigned but unsaved parent as valid" do
.should be_valid
.should be_valid
end
it "works when you save the parent" do
.should be_valid
.save
.should be_valid
.should be_valid
end
end
Created by Ashley Moran - 2009-07-07 09:38:23 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/957
该提问来源于开源项目:datamapper/dm-core