问题
Is there a way to prevent Doctrine from assigning a contraint on both sides of a one-to-one relationship? Ive tried moving the definition from one side to the other and using owning side but it still places a constraint on both tables. when I only want the parent table to have a constraint - ie. its possible for the parent to not have an associated child.
For example iwant the following sql schema essentially:
CREATE TABLE `parent_table` (
`child_id` varchar(50) NOT NULL,
`id` integer UNSIGNED NOT NULL auto_increment,
PRIMARY KEY (`id`)
);
CREATE TABLE `child_table` (
`id` integer UNSIGNED NOT NULL auto_increment,
`child_id` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`child_id`),
CONSTRAINT `parent_table_child_id_FK_child_table_child_id`
FOREIGN KEY (`child_id`)
REFERENCES `parent_table` (`child_id`)
);
However im getting something like this:
CREATE TABLE `parent_table` (
`child_id` varchar(50) NOT NULL,
`id` integer UNSIGNED NOT NULL auto_increment,
PRIMARY KEY (`id`),
CONSTRAINT `child_table_child_id_FK_parent_table_child_id`
FOREIGN KEY (`child_id`)
REFERENCES `child_table` (`child_id`)
);
CREATE TABLE `child_table` (
`id` integer UNSIGNED NOT NULL auto_increment,
`child_id` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`child_id`),
CONSTRAINT `parent_table_child_id_FK_child_table_child_id`
FOREIGN KEY (`child_id`)
REFERENCES `parent_table` (`child_id`)
);
I could just remove the constraint manually or modify my accessors to return/set a single entity in the collection (using a one-to-many) but it seems like there should built in way to handle this.
Also im using Symfony 1.4.4 (pear installtion ATM) - in case its an sfDoctrinePlugin issue and not necessarily Doctrine itself.
回答1:
sfDoctrinePlugin configures doctrine model builder in way that creates opposite side relations automatically. In PHP 5.2 you can't do anything with it.
As of PHP 5.3, where ReflectionProperty::setAccessible() method is available, you could manipulate protected/private properties of Doctrine_Relation_Parser
instance which can be obtained by $this->getTable()->getRelationParser()
. So you have to override BaseSomething::setUp()
method and drop unneeded relations manually using php's reflection API. You have to use reflection API because Doctrine_Relation_Parser
doesn't provide a method which allows to drop relations at will.
回答2:
I've solved this by setting the doctrine state for the opposite "null object" BEFORE we save the record:
/* @var $address Address */
$address = $form->getObject();
// the null object is here the "address position", let's change it's state
$address->getAddressPosition()->state(Doctrine_Record::STATE_CLEAN);
// now we can save the address and doctrine won't insert the null object
$address = $form->save();
来源:https://stackoverflow.com/questions/2623941/doctrine-1-2-how-do-i-prevent-a-contraint-from-being-assigned-to-both-sides-of