10

问题

无论我使用的是 Eloquent 还是 Query Builder,我都想自动在 Laravel 4 中对数据库表的每次插入/更新添加created_by和字段。modified_by但是,并非我的所有表都有这些字段,因此任何解决方案都必须在添加之前检查这些列是否存在。

尝试的解决方案

我扩展了Illuminate\Database\Eloquent\Model该类并编写了一个覆盖方法save(),以便为每个保存的记录添加一些额外的元数据字段。

这很好,除非我使用查询生成器执行插入,然后绕过。查看Model该类,似乎数据库操作实际上是使用查询构建器完成的。

我查看了Illuminate\Database\Query\Builder模型,看起来我可以为insert()and编写覆盖方法update()

这是为每次插入/更新执行某些任务的明智方法,还是我以后会遇到麻烦?

4

5 回答 5

12

添加到上述答案。你可以做这样的事情。

在 app/models 中创建一个名为 BaseModel.php 的类,扩展 \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;
    });
  }

}

然后在您的个人模型类中,您需要扩展 BaseModel 而不是 \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();
    }

}

现在,每当您保存或更新模型时,created_by 和 updated_by 字段都会自动更新。

注意:这仅在通过 Eloquent 完成保存或更新时才有效。对于查询构建器,您可以使用通用方法来获取和附加 created_by 和 update_by 列更新。

于 2014-09-20T14:19:08.810 回答
7

您绝不能覆盖 save 方法来覆盖和添加您的功能。

您必须使用 eloquent 提供的模型事件功能来代替。

简而言之,您必须为模型定义一个保存事件,以覆盖/设置/检查模型将要保存的数据。

放入 User 模型类的简单示例:

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

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

更多信息: http: //four.laravel.com/docs/eloquent#model-events

于 2013-08-23T09:03:23.447 回答
4

在 Laravel 中,如果您想在每次保存/更新时从单个点调用单个方法,而不在每个扩展模型中进行任何其他更改,您可以为 eloquent 事件自定义侦听器。正如文档所说,它只能针对每个模型完成。但是创建自定义侦听器允许访问任何模型中的任何事件。

只需boot()在下面的方法中添加一个侦听器EventServiceProvider并进行相应的修改。

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

请注意,通配符用于匹配任何模型。有关事件的更多信息,请参阅文档

于 2017-01-05T08:58:43.093 回答
2

如果你想使用 Query Builder 和 Eloquent 来解决这个问题而不扩展核心组件(我认为没有必要),你可以只使用Event System

链接: http: //laravel.com/docs/events

因此,您将使用诸如 之类的事件user.custom.save,然后创建一个与查询构建器一起使用的函数,该函数最终将触发此事件,与 Eloquent 相同。

例子:

class User extends Eloquent
{
    public function save()
    {
        Event::fire('user.custom.save', array($this));
        parent::save();
    }
}
于 2013-08-23T10:02:17.117 回答
0

您可以使用 Venturecraft 可修订包,因为在此包中的表中,您需要的所有信息都已存储,您只需要此包以优雅的方式获取它们: https ://github.com/fico7489/laravel-revisionable-upgrade

于 2017-12-06T18:00:04.277 回答