是否可以暂时禁用Laravel中的活动?

kdfy810k  于 2022-12-14  发布在  其他
关注(0)|答案(8)|浏览(170)

我在'saved'模型事件中有以下代码:

Session::flash('info', 'Data has been saved.')`

所以每次保存模型时,我都可以有一个flash消息通知用户。问题是,有时我只需要更新一个字段,比如'status'或者增加一个'counter',我不需要flash消息。那么,是否可以暂时禁止触发模型事件?或者是否有任何Eloquent方法,比如$model->save(),不触发'saved'事件?

wlsrxk51

wlsrxk511#

Laravel 8.x和9.x的解决方案

有了Laravel 8,这变得更加简单,只需使用saveQuietly方法:

$user = User::find(1);
$user->name = 'John';

$user->saveQuietly();

Laravel 8.x文档
Laravel 9.x文档

Laravel 7.x、8.x和9.x的解决方案

在Laravel 7(或8或9)上,按以下方式 Package 抛出事件的代码:

$user = User::withoutEvents(function () use () {
    $user = User::find(1);
    $user->name = 'John';
    $user->save();

    return $user;
});

Laravel 7.x文档
Laravel 8.x文档
Laravel 9.x文档

Laravel版本从5.7到6.x的解决方案

以下解决方案适用于Laravel版本5.7到6.x,对于较早版本,请检查答案的第二部分。
在模型中添加以下函数:

public function saveWithoutEvents(array $options=[])
{
    return static::withoutEvents(function() use ($options) {
        return $this->save($options);
    });
}

然后按以下步骤保存而不保存事件:

$user = User::find(1);
$user->name = 'John';

$user->saveWithoutEvents();

有关详细信息,请查看Laravel 6.x文档

适用于Laravel 5.6及更早版本的解决方案。

在Laravel 5.6(及以前的版本)中,您可以禁用并再次启用事件观察器:

// getting the dispatcher instance (needed to enable again the event observer later on)
$dispatcher = YourModel::getEventDispatcher();

// disabling the events
YourModel::unsetEventDispatcher();

// perform the operation you want
$yourInstance->save();

// enabling the event dispatcher
YourModel::setEventDispatcher($dispatcher);

有关更多信息,请查看Laravel 5.5文档

3vpjnl9f

3vpjnl9f2#

泰勒的Twitter页面上有一个很好的解决方案:
将此方法添加到您的基础模型中,或者如果您没有基础模型,则创建一个特征,或将其添加到当前模型中

public function saveQuietly(array $options = [])
{
    return static::withoutEvents(function () use ($options) {
        return $this->save($options);
    });
}

然后在你的代码中,每当你需要保存你的模型而不触发事件时,就使用这个:

$model->foo = 'foo';
$model->bar = 'bar';

$model->saveQuietly();

非常优雅和简单:)

fivyi3re

fivyi3re3#

调用模型对象,然后调用unsetEventDispatcher,之后您可以执行任何您想要的操作,而无需担心事件触发
就像这张:

$IncidentModel = new Incident;
    $IncidentModel->unsetEventDispatcher();

    $incident = $IncidentModel->create($data);
pexxcrt2

pexxcrt24#

为了回答这个问题,您可以使用unsetEventDispatcher()方法禁用示例上的模型侦听器:

$flight = App\Flight::create(['name' => 'Flight 10']);
$flight->unsetEventDispatcher();
$flight->save(); // Listeners won't be triggered
gv8xihay

gv8xihay5#

在laravel 8.x中:

保存无事件的单个模型

有时候你可能希望“保存”一个给定的模型而不引发任何事件。你可以使用saveQuietly方法来实现这一点:

$user = User::findOrFail(1);

$user->name = 'Victoria Faith';

$user->saveQuietly();

参见Laravel文档

cig3rfwq

cig3rfwq6#

在laravel 7.x中,您可以像以下操作一样简单

use App\User;

$user = User::withoutEvents(function () {
    User::findOrFail(1)->delete();

    return User::find(2);
});

有关更多信息,请参阅Laravel 7.x静音事件文档

agxfikkp

agxfikkp7#

您不应该将会话 Flink 与模型事件混合-当发生某些事情时,模型不负责通知会话。
控制器最好在保存模型时调用会话flash。
这样,您就可以控制何时实际显示消息,从而解决问题。

rxztt3cl

rxztt3cl8#

虽然这个问题已经提出很久了,但我已经找到了一种方法来一次关闭所有事件。在我的例子中,我正在制作一个迁移脚本,但我不希望任何事件被触发(无论是从Eloquent还是其他任何地方)。
问题是从Event类中获取所有事件,并使用forget方法删除它们。
在我的命令内:

$events = Event::getRawListeners();
foreach ($events as $event_name => $closure) {
    Event::forget($event_name);
}

相关问题