Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

CakePHP:Criando uma nova linha HABTM em vez atualiza outras


Ok, aqui está o que eu penso está acontecendo:

Você não está usando a mágica super útil da relação HABTM. Em vez de tratar esta tabela como uma mera tabela de relações, cake vai para o modelo definido e vê as relações que você definiu e primaryKeys e displayFields, etc.

Tudo bem quando você tem uma tabela HABTM complicada. Mas se for esse o caso, sua matriz de dados está toda bagunçada, porque você não está adicionando uma Question e Qset separadamente. O que quero dizer é que você não está fazendo
$data = array('Question'=>array('title'=>'new_question'),
              'Qset'=>array('name'=>'lets say qset'));
$this->Question->saveAll($data);

Fazendo isso, você deixa o cake resolver a associação HABTM para você, e essa estrutura de dados estaria ok. Mas você tem seu próprio modelo QsetsQuestion em sua pasta de modelos. Portanto, os dados que você salva devem ser como em qualquer outra tabela, assim
$data = array('qset_id'=> $qset_id,
              'question_id'=> $question_id);
$this->Question->QsetsQuestion->save($data);

E isso cria um novo id na tabela qsets_questions, com a nova relação, exatamente como você deseja.

Tenha cuidado, no entanto, já que você está usando seu próprio modelo para isso, se você não definir suas validações corretamente, poderá ter o mesmo par de chaves estrangeiras muitas vezes, porque, por padrão, basta verificar se o id deve ser exclusivo .

[EDITAR] Após um pouco de esclarecimento, a solução acima resolve o "problema", mas não é realmente o motivo desse comportamento.

Cakephp tem um recurso

Portanto, quando você deseja adicionar uma nova linha, o cake exclui todas as associações anteriores e adiciona as novas. Uma maneira de resolver isso é encontrar todos os Qsets que pertencem a uma pergunta e adicione-os ao $data array (com a adição da nova associação de pergunta que você deseja adicionar). Este link me ajudou a entender as associações HABTM (procure por "Desafio IV").

Eu sei que a solução que dei antes ajudou você com o "problema", mas foi feita com a impressão de que você tinha um QsetsQuestion arquivo de modelo em algum lugar. Como você não tem, a solução seria obter todas as Questions associados e adicione-os como um novo array. Ou criar uma QsetsQuestion model e faça as associações assim:
Qset hasMany QsetsQuestion
QsetsQuestion belongsTo Qset, Question
Question hasMany Qsets.

Ou mudar o comportamento do bolo... Nenhum deles parece bonito, eu sei.

Então, resumo para soluções:

  • Toda vez que você quiser salvar uma nova associação Qset-Question, recupere as associações armazenadas anteriormente, coloque-as no array a ser salva e salve-as
    //find previously associated Qsets, lets say it's 1,2,3 and 4
    $data = array('Question'=>array('id'=>1),
              'Qsets'=>array('Qsets'=>array(1,2,3,4, $new_qset));
    $this->Question-save($data);
    

Observe que não há QsetsQuestion , pois não existe. Esta deve ser a primeira opção, pois o modelo HABTM não é complexo

OU

  • Criar QsetsQuestion na pasta do seu modelo e altere as associações conforme indicado acima. A parte de salvamento no controlador seria
    $data = array('qset_id'=>1, 'question_id'=>1)
    $this->Question->QsetsQuestion->save($data);    //also works with $this->Qset->QsetsQuestion
    

É muito mais simples (talvez), mas você precisa criar um novo arquivo e lembre-se de verificar se não há associação semelhante anterior (verifique se existe tupla 2-2 antes de inseri-la). Regras de validação simples devem funcionar.

OU
  • Alterar o comportamento do cakephp para este... Não gosto deste.