Laravel:在使用Query Builder或Eloquent ORM时,在每次插入/更新时执行一些任务

时间:2013-08-23 08:40:48

标签: php laravel laravel-4 eloquent query-builder

问题

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

尝试解决方案

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

这很好,但是如果我使用查询生成器执行插入操作,那么这将被绕过。查看Model类,看起来数据库操作实际上是使用查询构建器完成的。

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

对于每次插入/更新执行某项任务,这是一种明智的方法,还是稍后会遇到麻烦?

5 个答案:

答案 0 :(得分:8)

添加上述答案。你可以这样做。

在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列更新。

答案 1 :(得分:7)

您绝不能覆盖保存方法以覆盖并添加您的功能。

你必须使用雄辩提供的模型事件功能,而不是这样做。

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

放入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

答案 2 :(得分:1)

如果你想使用查询生成器,并且在没有扩展核心组件(我认为不必要的话)的情况下以唯一的方式解决这个问题,你可以使用事件系统

链接: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();
    }
}

答案 3 :(得分:0)

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

只需在boot()中添加EventServiceProvider方法的监听器,如下所示,并进行相应修改。

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

请注意,用于匹配任何型号的通配符。有关活动的详情,请参阅documentation

答案 4 :(得分:0)

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