3分钟短文 | Laravel模型关联删除表记录,用观察者还是事件钩子

引言
说一个场景需求 , 假如有一个user模型 , 用户的上传图片存在另外一张表photo内 。 当删除该用户时 , 想要同时删除关联的photo表的相关记录 。 应该用什么办法呢?
3分钟短文 | Laravel模型关联删除表记录,用观察者还是事件钩子
文章图片
本文就来说说LaravelORM操作中的事件钩子 。
学习时间
如果想要实现上一节所说的需求 , 代码写起来可能是这样的 。
$user->delete();
【3分钟短文 | Laravel模型关联删除表记录,用观察者还是事件钩子】当该事件发生时 , 我们接着执行关联的删除 。
$this->photo()->delete();
如果程序中每个地方逻辑上进行了删除操作 , 岂不是都要手动这么重复写 , 这些重复代码真的是无用功 。
那么Laravel中是怎么写的呢 , 如何自动在触发了user的删除时间 , 自动进行photo的删除操作?我们可以借助于EloquentORM提供的deleting事件 , 做删除动作 。
代码如下:
3分钟短文 | Laravel模型关联删除表记录,用观察者还是事件钩子
文章图片
只用在Model模型类中继承并实现boot犯法 , 然后调用模型的deleting事件 , 使用回调声明执行的动作即可 。
这样在删除动作上只用维护一处代码 , 程序内所有的delete事件都会自动触发该动作 , 复用率大大地提升了 。
再进一步
实现同样的需求 , 往往有很多种方式 。 你还可以换用一种事件钩子方式 , 就是Laravel提供的观察者(Observers)方式 。
首先 , 在AppServiceProvider内注册某模型的观察者:
publicfunctionboot(){User::observe(UserObserver::class);}
然后添加观察者类UserObserver:
classUserObserver{publicfunctiondeleting(User$user){$user->photos()->delete();}}
这样就用观察者盯着User模型的动作 , 如果发现 , 立即执行UserObserver内对应的动作 。
这样把程序功能单独摘开 , 调试的时候非常方便 。 而且对于后期有修改 , 或者复杂的动作 , 处理起来就会游刃有余 , 不会把代码逻辑写的一堆又一堆 , 在事件方法内 , 你只需集中处理一次就够了!
这才是有弹性的代码!鲁棒性非常好的代码!
不推荐的方法
还有一种方法 , 我们本不打算推荐 , 但是考虑到有的初学者容易犯此类错误 , 就拿出来最为参照 。
程序功能应该单一 。 比如 , 尽量避免把数据关联操作放到数据库执行 。 MySQL提供了外键约束 , 并且可以定义触发器用于批次动作处理 。
那么使用Laravelmigrations时 , 创建photo表的外键关联事件:
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
这样做 , 就是把动作交给了MySQL处理 。
非常不利于程序调试 , 和数据全程追溯!不推荐使用!
写在最后
本文通过3种方式 , 实现了Laravel中关联删除表记录的功能 。 推荐写法是第一种 , 直接在模型内声明事件钩子 , 处理起来较为方便;
第二种会造成虽然整洁 , 但是如果注册的观察者过多 , 不易于模型与观察者之间的关联调试;
第三种方式 , 完全不推荐 , 我们不应该把数据有效性和完整性的操作交给MySQL 。
Happycoding:-)
我是@程序员小助手 , 持续分享编程知识 , 欢迎关注 。


    推荐阅读