vistas vista variable una softdelete definir declarar laravel laravel-4 eloquent cascading-deletes

vista - Cómo hacer una cascada en softdeletes en Laravel4?



softdelete laravel (3)

Intenté usar claves externas con delete cascade y softDeletes sin mucha suerte.

Tengo 2 tablas: usuarios, eventos. Ambas tablas tienen softDeletes.

Los usuarios pueden tener 0..n Eventos.
Los eventos tienen un user_id, usado como clave externa en los usuarios, así:

$table->foreign(''user_id'')->references(''id'')->on(''users'')->onDelete(''CASCADE'')->onUpdate(''CASCADE'');

El problema es que cuando elimino un usuario, se borra suavemente, pero sus eventos no lo hacen, ya sea eliminación suave o eliminación física.

¿Estoy haciendo algo mal o este es el comportamiento Eloquente correcto?

En segundo lugar, si ese es el comportamiento correcto, ¿cómo implementar mejor la cascada de eliminación? tal vez anulando el método delete () en mis modelos como este ...

public function delete() { //delete all events... __parent::delete() }

?


Estás pensando demasiado en esto.

Simplemente elimine los eventos justo antes de eliminar los usuarios:

$user->events()->delete(); $user->delete();

O cree una función de eliminación de clientes en el modelo de usuario:

public function customDelete(){ $this->events()->delete(); return $this->delete(); }

También podría agregar un observador modelo y observar el evento de eliminación o eliminación, pero en el escenario que mencionó anteriormente, los dos métodos anteriores serían una solución más simple.

http://laravel.com/docs/4.2/eloquent#model-observers


Si entiendo correctamente, ¿estás intentando conectar a los softdeletes en cascada en ambas mesas?

Creo que hacer esto con ON UPDATE CASCADE no es el enfoque correcto. Trataré de explicar por qué ...

Para intentar hacer esto, debe crear una relación de clave externa a clave compuesta.

es decir, debe vincular (events.user_id y deleted_at) a (user.id y delete_at). Cambia uno, actualizará el otro.

Primero, deberá agregar una regla predeterminada a sus columnas deleted_at, ya que no puede vincular valores nulos.

Así que agregue sus migraciones para ambas tablas ... $table->softDeletes()->default(''0000-00-00 00:00:00'');

Agregue a su tabla de usuario una clave única usando ''id'' y ''deleted_at''

Schema::table(''users; function($table) { $table->unique(array(''id'',''deleted_at'')) });

Luego, en la tabla de eventos, cree una clave externa como esa (enlaces a la clave única)

Schema::table(''events; function($table) { $table->foreign(array(''user_id'',''deleted_at''),''events_deleted_at_foreign_key'')-> }->references(array(''id'',''deleted_at''))->on(''users'')->onUpdate(''CASCADE''));

Ejecuta esto, ahora deberías encontrar que si borras suavemente a tu usuario, borrará suavemente sus ''eventos''.

Sin embargo, si ahora intentas borrar un evento de forma suave, fallará en la restricción de la clave externa. ¿Por qué puedes preguntar?

Bueno, lo que estás haciendo es crear una relación de Parent Child usando id, deleted_at en ambas tablas. Al actualizar el padre, se actualizará el niño. Y la relación es ininterrumpida. Sin embargo, si Actualizas al niño, la relación ahora está rota, dejando al niño como un huérfano en la mesa. Esto falla la restricción de clave externa.

Así que una respuesta larga, pero con suerte una buena explicación de por qué lo que estás tratando de hacer no funcionará y te ahorrará mucho tiempo tratando de hacer esto con ON UPDATE CASCADE. Acceda a los GATILLO, y active una función para manejar lo que está tratando de hacer, o manejarlo en su aplicación. Personalmente, lo haría con TRIGGERS para que la base de datos siga siendo su propia entidad y no tenga que depender de nada para mantener la integridad de los datos.

delimiter //

CREATE TRIGGER soft_delete_child DESPUÉS DE ACTUALIZAR EN db.users PARA CADA FILO INICIAR SI NEW.deleted_at <> OLD.deleted_at LUEGO UPDATE eventos SET deleted_at = NEW.deleted_at WHERE events.user_id = NEW.id; TERMINARA SI; FIN;

// delimitador;


La clave externa del DB no hará nada porque no ha cambiado la clave primaria en cuestión. Solo si actualiza o elimina la clave principal, las filas relacionadas se modificarán.

De todo lo que puedo encontrar sobre este tema, la solución es usar los eventos modelo de Eloquent para escuchar un evento de eliminación y actualizar las tablas relacionadas.

Aquí hay una pregunta de al respecto.

Alternativamente, puede "extender" el método delete() e incluir la funcionalidad directamente también. Aquí hay un ejemplo.