Pregunta Laravel: realizar alguna tarea en cada inserción / actualización cuando se utiliza el Generador de consultas o el ORM elocuente


El problema

Me gustaría añadir automáticamente created_by y modified_by campos a cada inserción / actualización a una tabla de base de datos en Laravel 4, independientemente de si estoy usando Eloquent o Query Builder. Sin embargo, no todas mis tablas tienen estos campos, por lo que cualquier solución deberá verificar estas columnas antes de agregarlas.

Intento de solución

He extendido el Illuminate\Database\Eloquent\Model clase y escrito un método de sobrescritura save() para agregar algunos campos de metadatos adicionales para cada registro que se guarda.

Esto está bien, excepto que si realizo una inserción utilizando el Generador de consultas, esto se omite. Mirando a la Model clase, parece que las operaciones de la base de datos se realizan realmente con el generador de consultas.

He echado un vistazo a la Illuminate\Database\Query\Builder modelo y parece que probablemente podría escribir métodos de sobrescritura para insert() y update().

¿Es esta una forma sensata de realizar alguna tarea para cada inserción / actualización o me voy a meter en problemas más adelante?


5
2017-08-23 08:40


origen


Respuestas:


Añadiendo a las respuestas anteriores. Podrías hacer algo como esto.

Cree una clase en la aplicación / modelos llamada BaseModel.php extended \ Eloquent

class BaseModel extends \Eloquent{

public static function boot()
{
    parent::boot();

    static::creating(function($model)
    {
        //change to Auth::user() if you are using the default auth provider
        $user = Confide::user();
        $model->created_by = $user->id;
        $model->updated_by = $user->id;
    });

    static::updating(function($model)
    {
        //change to Auth::user() if you are using the default auth provider
        $user = Confide::user();
        $model->updated_by = $user->id;
    });
  }

}

Luego, en sus clases modelo individuales, necesita ampliar el Modelo base en lugar de \ Eloquent

class Product extends BaseModel {

    protected $table = 'product';

    //Booting the base model to add created_by and updated_by to all tables
    public static function boot()
    {
        parent::boot();
    }

}

Ahora, cada vez que guarde o actualice un modelo, los campos created_by y updated_by se actualizarán automáticamente.

Nota: Esto solo funcionaría cuando se guarde o actualice a través de Eloquent. Para el generador de consultas, puede tener un método común para buscar y agregar las actualizaciones de columna created_by y update_by.


7
2017-09-20 14:19



Nunca debe anular el método guardar para anular y agregar su funcionalidad.

Debe utilizar la funcionalidad de eventos modelo que elocuente proporciona para hacerlo en su lugar.

En pocas palabras, debe definir un evento de guardado para su modelo para anular / establecer / verificar los datos que el modelo va a guardar.

Un ejemplo simple para poner en una clase de modelo de usuario:

//Executed when loading model
public static function boot()
{
     parent::boot();

     User::creating(function($user){
         $user->value1 = $user->value2 +1;
     });
}

Más información: http://four.laravel.com/docs/eloquent#model-events


5
2017-08-23 09:03



Si desea utilizar el Generador de consultas, y Eloquent es la única forma de evitar esto sin ampliar los Componentes principales (que no considero necesarios), puede usar el Sistema de eventos.

Enlazar: http://laravel.com/docs/events

Así que usarías un evento como user.custom.save, luego cree una función para usar con el generador de consultas que al final desencadenaría este evento, igual que con Eloquent.

Ejemplo:

class User extends Eloquent
{
    public function save()
    {
        Event::fire('user.custom.save', array($this));
        parent::save();
    }
}

1
2017-08-23 10:02



En Laravel 5.3 si quieres llamar a un Método único en cada guardado / actualización desde un solo punto Sin realizar cambios adicionales en cada uno de los modelos extendidos., puedes tener un escucha personalizado para eventos elocuentes. Como documetación dice que se puede hacer solo por modelo. Pero crear un oyente personalizado permite acceder a cualquier evento en cualquier Modelo.

Solo agrega un oyente a boot() método en EventServiceProvidercomo a continuación y modificar en consecuencia.

Event::listen(['eloquent.saving: *', 'eloquent.creating: *'], function(){
        //your method content
        //returning false will cancel saving the model
 });

Tenga en cuenta que el comodín utilizado para que coincida con cualquier modelo. Ver documentación para más sobre eventos.


0
2018-01-05 08:58



Puede usar el paquete revisable de venturecraft porque en una tabla de este paquete toda la información que necesita ya está almacenada, solo necesita este paquete para obtenerlos de una manera elegante: https://github.com/fico7489/laravel-revisionable-upgrade


0
2017-12-06 18:00