laravel Eloquent save 触发了哪些事件
记录一下laravel Eloquent 事件的使用
需求是这样的,如果在订单状态改变的时候给对应的用户发送消息,拽过来同事开始讨论
- 当然第一个想到的就是用Eloquent的事件,订单状态变了,会触发事件,但是Eloquent的这些updated,saved事件怎么知道是订单状态变了,而不是其他值改变了触发的呢?消息里面需要用到订单原来的属性怎么办?
- 或者就是controller处理完逻辑,改变了订单的状态自己触发一个事件,
那么是不是触发事件需要传入原来的订单的属性和改变后的属性呢?这样listener才能确切的知道订单的状态是怎么变得,然后发送对应的消息? - 或者压根不触发事件,直接在controller中处理这个逻辑,因为controller明白到底发生了什么,直接发送消息,想怎么发怎么发
我们有好多好多的订单,好多好多的地方会改变订单状态,显然2,3两个方案太扯淡了,每个处理逻辑的地方都需要增加代码,处理一堆逻辑,写着就不爽,维护起来不是要疯了?
好吧我们来看看laravel Eloquent save的时候到底触发了哪些事件
|
|
首先触发的当然是saving
,如果saving返回的是false,那么save就失败了,返回false
接着如果$this->exists,就是这个model不是新创建的,那么就需要进行更新操作
|
|
看看更新干了什么,
首先如果这个模型dirty了,也就是脏了,也就是有属性改变了,那么才需要更新
先触发
updating
,更新失败了就false,更新时间戳
这里又判断了count($dirty) > 0,为什么??更updateTimestamps有什么关系吗?没有仔细看,以后再说吧
然后执行update,也就是写入了数据库
- 最后触发
updated
那么如果这个对象是新建的,也就是需要执行插入操作,performInsert也做了差不多的事,
- 触发
creating
, - 执行insert,插入数据库,
- 最后
created
。
最后回到save方法,如果更新或者插入操作成功了,那么就finishSave来结束save,
finishSave 触发了saved
事件, 最后syncOriginal。
小结一下
- 新创建的对象,save依次触发
saving
->creating
->created
->saved
- 已存在的对象,save依次触发
saving
->updating
->updated
->saved
好了知道了我们知道了model save的时候触发了哪些事件,但是还是没有解决我们的问题啊,到底是因为状态改变了触发的还是因为订单其他的值改变了触发的呢?订单原来的状态怎么获取呢?
这就需要看看isDirty和syncOriginal是怎么回事了
打印过Eloquent 对象的应该都会发现,其实模型会有两个数组,一个original,一个attributes。
这下应该就明白了,初始化一个模型的时候这两个数组是一样的,赋值操作只是改变attributes,所以isDirty也就是根据两个数据来判断模型是否dirty了,模型触发完saved
事件后才会执行syncOriginal,syncOriginal也就是将attributes赋值给original。所以上面触发的所有事件,我们都是能拿到原来的值和变化的值得。
所以我们的问题也就解决了,当模型触发updated
事件的时候,我们根据isDirty([‘status’]) 知道订单状态改变了,然后拿到订单之前是个什么样子,改变后是个什么样子,该发什么消息也就很明朗了。
laravel设计的好牛逼,事实教育我们,要多看文档,多看代码。幸好我机智的看了代码,要是用了2,3两个方案,我不是该哭了?