Laravel 中自定义模型中间表(请使用合适的方法来解决问题)

翻译 Summer ⋅ 于 6个月前 ⋅ 1602 阅读 ⋅ 原文地址

站点的翻译文章创建时,您将第一时间收到通知。

这是一篇社区协同翻译的文章,已完成翻译,更多信息请点击 协同翻译介绍

几天前在 tweet 看到这个:

file

我的第一反应是,「一定有」。这种类型的事情,恰恰我觉许多人都是写利害评论,而不是简单的说说,经常掩盖甚至没有意识到。 Laravel 是「顽固的」,但通常意味着有很多默认设置将你推向一种特定风格。多年以来我发现很少的情况下,你不能轻松的覆盖这些;往往,当你实例化时,它只是添加了另一个函数调用。

通常,当我想到我的代码出现 Mark的问题时, 从文档中搜索和发现更直接的答案,在我看来,这是一个很好的例子。

rayle 翻译于 6个月前

首先,用正常的工作方式检查一下中间表。在这个例子中我们有一个多对多 UsersSubjects 之间的关系。因此,一个典型的 update 语句看起来像是:

User::find($id)->subjects()->updateExistingPivot($subjectId, ['status' => 'enrolled']);

如果你想要在这个语句下调度一个事件或是有其他任务,你可以写在这条语句下面。如果你希望在你的整个项目中使用,你预先把这条语句写成一个服务类函数,这样就可以在任意一个地方 update

这样运行,没有什么内在「错误」。这样 做 感觉有点程序化,不过,难道不是吗? 让你感觉也许有些你可以做的更好?假如,这段代码是全局要使用,但是我们 没有在服务类中创建它?如果在每个不同的操作中,有很多中间表的字段要被更新?

这样编写程序变得「困难」。不是编写代码,而是设计代码。先考虑如何使用这个类,并作出明智的选择,而不是仅仅放在你学习到的技术。因为它很简单,你可以从其他地方复制/粘贴,没有记住它是如何使用的(经验之谈,不要感到是攻击)。

例如,如果这个中间表包含的信息是有用的,本身独立于 users 和特定的 subjects? 这样的情况下,你可能选择建立自己的实体,完整的控制器,模型,验证规则。这个想法在过去一年越来越强烈了;你可能会喜欢听Full Stack Radio插曲 ,DHH讨论如何建立一个 BaseCamp 时的中心思想。 UserSubject也许是事情本身,你创建,更新和报告 。重要的是意识到中间表类在 Laravel默认选择的,而不是可选的。

rayle 翻译于 5个月前

第二个选项---可能是最常见的---就是按照我们上面描述的方法来创建一个UserSubjectService类。任何时候你想要更新链接数据库,你都要经过服务类的update()函数。这使您可以完全控制流程的每个步骤,同时使所有内容都完全透明。当然,这是完全可以测试的。其中一些缺点可能是不断声明新类的所有开销,将用户,主题和更新数据的实例传递给它,并可能在需要单独更新函数的任何地方调用相同的事件函数。服务类更常用于管理其他几个类,所以如果我们在用户和主题之间做了很多的工作,或者增加了额外的功能,这将是一个不错的选择。对于像我们以后那样简单的事情,这可能太多了。

我会告诉你的最后一个选项就是覆盖Laravel默认值的一个例子。我们已经知道,每个Eloquent模型都有Observers - 内置在模型中的许多常见动作的侦听器钩子中,比如completedsaving...和update。既然我们想在每次数据透视表更新的时候触发一个事件,我们只需要进入这个模型。

雄辩使用了一种叫做「等待」的特殊模式---一个在Illuminate\Database\Eloquent\Relations\Pivot中找到的枢轴,是一个模型的继承类,它具有处理多对多的功能,很多关系。为了定制这些函数中的任何一个,我们首先扩展Pivot,例如class UserSubject extends Pivot来添加我们的代码,然后调用我们的模型关系函数来调用它:

class Subject extends Model
{
    public function users()
    {
        return $this->belongsToMany('App\User')
            ->using('App\UserSubject');
    }
}
阿文 翻译于 6个月前

现在每当关系被调用的时候,任何你添加到你自己的类中的东西都就像继承的模型一样会被访问。 在这个特定的情况下,我们将注册一个UserSubjectObserver类,并将代码添加到updating()updated()方法中。

三种方法都可以实现同样的事情 -- 但并没有说这所罗列的就是所有的解决方式了。 本文的重点,除了介绍Pivot类和using()函数之外,还让你意识到用Laravel方法来编程的优势,但是最终设计代码还要靠你自己!

RyanFeng 翻译于 6个月前

原文地址:https://medium.com/@codebyjeff/custom-pi...

译文地址:https://laravel-china.org/topics/7510/cu...


本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

本帖已被设为精华帖!
回复数量: 0
    暂无评论~~
    您需要登陆以后才能留下评论!

    Composer 中国全量镜像

    Top 100 扩展包

    Lumen 中文文档

    Laravel 速查表

    Laravel 中文文档

    Laravel 项目开发规范

    Laravel 开发环境部署

    Elasticsearch-PHP 中文文档

    Lumen 中文文档

    GraphQL PHP 中文文档

    社区文档撰写指南

    TDD 构建 Laravel 论坛笔记

    PHP PSR 标准规范

    PHP 设计模式全集

    Dingo API 中文文档