Doutrina 1.2: Como evito que uma contradilhe seja atribuída a ambos os lados de uma relação individual?
-
26-09-2019 - |
Pergunta
Existe uma maneira de impedir que a doutrina atribua uma contratação em ambos os lados de um relacionamento individual? Eu tentei mover a definição de um lado para o outro e usar o lado possuir, mas ela ainda coloca uma restrição nas duas tabelas. Quando eu só quero que a tabela pai tenha uma restrição - ou seja. É possível que os pais não tenham um filho associado.
Por exemplo, Iwant, o seguinte esquema SQL essencialmente:
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`)
);
No entanto, estou conseguindo algo assim:
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`)
);
Eu poderia simplesmente remover a restrição manual ou modificar meus acessores para retornar/definir uma única entidade na coleção (usando um um para muitos), mas parece que deve ser incorporado a maneira de lidar com isso.
Também estou usando o Symfony 1.4.4 (instalação de pêra ATM) - no caso de sua questão de sfdoctrineplugin e não necessariamente se doutrina.
Solução
O sfdoctrineplugin configura o construtor de modelos de doutrina da maneira que cria as relações laterais opostas automaticamente. No Php 5.2, você não pode fazer nada com isso.
A partir de Php 5.3, onde ReflectionProperty::setAccessible()
método está disponível, Você pode manipular propriedades protegidas/privadas do Doctrine_Relation_Parser
instância que pode ser obtida por $this->getTable()->getRelationParser()
. Então você tem que substituir BaseSomething::setUp()
Método e soltar relações desnecessárias manualmente usando a API de reflexão do PHP. Você tem que usar a API de reflexão porque Doctrine_Relation_Parser
Não fornece um método que permite abandonar as relações à vontade.
Outras dicas
Eu resolvi isso definindo o estado da doutrina para o "objeto nulo" oposto ANTES DA Nós salvamos o registro:
/* @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();