CakePHP HABTM: Edición de un elemento casuses fila HABTM para conseguir recreada, destruye los datos adicionales

StackOverflow https://stackoverflow.com/questions/2275353

Pregunta

Tengo problemas con mi relación HABTM en CakePHP.

Tengo dos modelos de este modo: Department HABTM Location. Una gran empresa tiene muchos edificios, y cada edificio ofrece un número limitado de servicios. Cada edificio tiene también su propia página web, lo que además de la relación HABTM sí, cada fila HABTM también tiene un campo url donde el usuario puede visitar para encontrar información adicional sobre el servicio que les interesa y cómo funciona en el edificio que' está interesado en.

He creado los modelos de esta manera:

<?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;
    }
}
?>

Los controladores son completamente sin interés.

El problema: Si puedo editar el nombre de un Location, todos los DepartmentsLocations que estaban vinculados a la Location se vuelven a crear con direcciones URL vacíos. Dado que los modelos precisan que única es cierto, esto también hace que todas las filas más nuevos para sobrescribir las filas de más edad, que destruye prácticamente la totalidad de las direcciones URL.

Me gustaría saber dos cosas: ¿Puedo detener esto? Si es así, ¿cómo?

Y, en un tono menos técnico y más whiney: ¿Por qué esto sucede incluso? Parece extraño para mí que la edición de un campo a través de la torta debe causar tantos problemas, cuando puedo ir fácilmente a través de phpMyAdmin, editar el nombre Location allí, y obtener exactamente el resultado que se puede esperar. ¿Por qué toca CakePHP los datos HABTM cuando estoy editando un campo en una fila? Ni siquiera es una clave externa!

¿Fue útil?

Solución

Desde el libro de cocina de la primera problema es:

  

Por defecto al guardar una   relación hasAndBelongsToMany, pastel   se eliminarán todas las filas en la tabla de unión   antes de guardar los nuevos.

No estoy seguro de por qué la torta está tratando de salvar los datos HABTM a pesar de que no tiene una clave externa en los datos, pero no hay una solución fácil para eso. Simplemente destruir la asociación para la llamar ahorra:

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

Otros consejos

Estoy pensando en una de las razones por qué esto podría estar sucediendo. Al recuperar Location, también recuperar datos locations_departments. Y cuando se hace una save($this->data) se ve en los modelos de la matriz y las guarda.

Una manera de resolver esto es establecer el atributo recursive (de un modelo) a -1 o 0 (trato, no estoy seguro, simplemente imprima la datos para ver lo que sale). Se puede establecer en el modelo: var $recursive = -1; o en el método controlador (acción): $this->ModelName->recursive = -1;

Más sobre recursiva: http://book.cakephp.org/view/439/recursive

Es muy similar a lo que harpax ha sugerido, simplemente si no es necesario que los datos, dilo a la torta, por lo que no va a buscarla.

El problema es que cuando el ahorro de su Location, que dio el método de guardar una matriz que contiene toda la DepartmentsLocations también. De este modo CakePHP destruye todo y tratar de volver a crearlo.

Este es un error común con la torta ya que a menudo se tire demasiados resultados para usted.

Asegúrese de pasar sólo los datos que necesita ser salvado, o mejor a buscar sólo los datos básicos que necesita.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top