Pergunta

Estou tendo problemas com meu relacionamento HABTM em CakePhp.

Eu tenho dois modelos como isso: Department HABTM Location. Uma grande empresa tem muitos edifícios e cada edifício fornece um número limitado de serviços. Cada edifício também tem sua própria página da web; portanto, além do relacionamento HABTM, cada linha HABTM também tem um url Campo onde o usuário pode visitar para encontrar informações adicionais sobre o serviço que estão interessadas e como ele opera no edifício em que está interessado.

Eu configurei os modelos como assim:

<?php
class Location extends AppModel {
    var $name = 'Location';

    var $hasAndBelongsToMany = array(
        'Department' => array(
            'with' => 'DepartmentsLocation',
            'unique' => true
        )
    );
}
?>


<?php
class Department extends AppModel {
    var $name = 'Department';

    var $hasAndBelongsToMany = array(
        'Location' => array(
            'with' => 'DepartmentsLocation',
            'unique' => true
        )
    );
}
?>

<?php
class DepartmentsLocation extends AppModel {
    var $name = 'DepartmentsLocation';

    var $belongsTo = array(
        'Department',
        'Location'
    );    


    // I'm pretty sure this method is unrelated. It's not being called when this error
    // occurs. Its purpose is to prevent having two HABTM rows with the same location
    // and department.
    function beforeSave() {

        // kill any existing rows with same associations
        $this->log(__FILE__ . ": killing existing HABTM rows", LOG_DEBUG);

        $result = $this->find('all', array("conditions" =>
            array("location_id" => $this->data['DepartmentsLocation']['location_id'],
                  "department_id" => $this->data['DepartmentsLocation']['department_id'])));


        foreach($result as $row) { 
            $this->delete($row['DepartmentsLocation']['id']);
        }

        return true;
    }
}
?>

Os controladores são completamente desinteressantes.

O problema:Se eu editar o nome de um Location, todos os DepartmentsLocations que estavam ligados a isso Location são recriados com URLs vazios. Como os modelos especificam que o único é verdadeiro, isso também faz com que todas as linhas mais recentes substituam as linhas mais antigas, o que destrói essencialmente todos os URLs.

Eu gostaria de saber duas coisas: posso parar com isso? Se sim, como?

E, em uma nota menos técnica e mais chorosa: por que isso acontece? Parece -me bizarro que a edição de um campo através do bolo deve causar tantos problemas, quando eu posso facilmente passar por phpmyadmin, editar o Location Nome lá e obtenha exatamente o resultado que eu esperaria. Por que o CakePhp toca os dados do HABTM quando estou apenas editando um campo em uma linha? Não é nem uma chave estrangeira!

Foi útil?

Solução

Do livro de receitas, o 1º problema é:

Por padrão, ao salvar um relacionamento de Hasandbelongstomany, o bolo excluirá todas as linhas na mesa de junção antes de salvar novas.

Não sei por que o bolo está tentando salvar os dados do HABTM, mesmo que você não tenha uma chave estrangeira em seus dados, mas existe uma solução fácil para isso. Simplesmente destruir a associação Para a chamada salvadora:

$this->Location->unbindModel(
    array('hasAndBelongsToMany' => array('Department'))
);

Outras dicas

Estou pensando em uma das razões pelas quais isso pode estar acontecendo. Quando você recupera Location, você também recupera locations_departments dados. E quando você faz um save($this->data) Ele procura modelos na matriz e os salva.

Uma maneira de resolver isso é definir o recursive atributo (de um modelo) a -1 ou 0 (tente, não tenho certeza, basta imprimir os dados para ver o que sai). Você pode defini -lo no modelo: var $recursive = -1; ou no método do controlador (ação): $this->ModelName->recursive = -1;

Mais sobre recursivo: http://book.cakephp.org/view/439/recursive

É realmente parecido com o que Harpax Sugerido, apenas se você não precisar desses dados, diga para bolo, para que não o busque.

O problema é que, ao salvar seu Location, você deu ao método salvar uma matriz contendo todo o DepartmentsLocations também. Assim, Cakephp destrói tudo e tenta recriá -lo.

Este é um erro comum com o bolo, pois geralmente puxa muitos resultados para você.

Certifique -se de passar apenas os dados que precisam ser salvos ou melhor buscar apenas os dados que você precisa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top