weixin_39782500 2020-11-22 01:58
浏览 0

Child with unsaved parent is invalid even when the parent is valid

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

  • 写回答

6条回答 默认 最新

  • weixin_39782500 2020-11-22 01:58
    关注

    Note - resolving this would remove the need for a proposed change in #940:

     ruby
    chainable do
      def save(context = :default)
        # ’save_parents && ’ added
        return false unless save_parents && (context.nil? || valid?(context))
        save_self && save_children
      end
    end
    

    by Ashley Moran

    评论

报告相同问题?