【问题标题】:Should I create three models or a polymorphic type我应该创建三个模型还是多态类型
【发布时间】:2020-10-12 19:05:10
【问题描述】:

我有一个 Laravel 8 应用程序,我想知道如何解决典型的 polymorphic 问题。我有一个Employee 模型。该员工可以是ExecutiveEmployeeEntryLevelEmployeeExecutiveEmployee 将有一些 EntryLevelEmployee 没有的方法,反之亦然。

使用 Laravel 8,是否可以创建一个基本的 Employee 模型(没有对应的表?),然后创建两个名为 ExecutiveEmployeeEntryLevelEmployee 的模型,它们继承自 Employee?这也意味着两种员工类型都有两个不同的数据库表,即使会有很多重叠的数据。

只拥有一个Employee 模型并创建一个模型中列出了员工类型的迁移是否有意义?我假设EntryLevelEmployee 有一些与它相关的数据库属性可能与ExecutiveEmployee 类型相关也可能不相关,或者这是一个不正确的假设?

在 Laravel 8 中建模的正确方法是什么?我更喜欢把所有东西都放在一张桌子上,因为这些模型非常相似。我确实必须记住,会有一个人拥有而另一个人没有的数据。也会有不同的访问器方法。

是否可以在使用多个模型时将所有内容都放在一个 employees 表中?意思是,如果我创建两个名为 ExecutiveEmployeeEntryLevelEmployee 的模型,它们都会查询基础表 employees

更新 1

我研究得越多,我就越认为多态在这里是不正确的方法,我可能需要的是Single-Table InheritanceThis package 似乎为 Eloquent 带来了这种能力。有充分的理由不使用它吗?

【问题讨论】:

  • ExecutiveEmployeeEntryLevevEmployee 是否需要在基本的users 表中出现(如果有的话)?第二个问题(或换句话说)每个用户(在users 表的情况下)是否都是[ExecutiveEmployee:class, EntryLevevEmployee:class] 中的一个?
  • @Tpojka 用户不是员工类型。
  • 我会去(我总是倾向于使用语言/技术/技术/框架推荐的命名约定)employeeable 多态表的表。而且,在那个多态枢轴中应该保留所有相互属性。 ExecutiveEmployeeEntryLevelEmployee 可以有它们的属性,如果需要,可以有单独的属性子表。是否应该是 1:1、1:n 或 m:n 多态关系取决于业务逻辑。
  • 如果每种类型的员工都有 3-5 列特定数据,我不明白为什么不将其全部简化并只制作一个 Employee 模型。以后管理起来要容易得多。但如果这两种类型有很多不同的信息,最好解耦。
  • 在我看来,使用 ORM 的目的是在关系数据库和 OOP 语言之间建立一个 OOP“桥梁”,所以从这个意义上说,如果为两者创建一个基类是有意义的其他类(即您想定义其他类将继承的基本行为)然后创建一个基类是正确的。

标签: laravel


【解决方案1】:

在这种情况下我会使用多态关系,因为你更灵活并且耦合更少。

使用Single Table Inheritance (STI),您可以在employees 表中添加特定类型的列,并将它们设为nullable。但请考虑将来添加/删除类型。

executive_employees
    id - integer
    executive_specific - string

entry_level_employees
    id - integer
    entry_level_specific - string

employees
    id - integer
    name - string
    email - string
    employable_id - integer
    employable_type - string

至于 STI 也是如此

employees
    id - integer
    name - string
    email - string
    type - string
    executive_specific - nullable string
    entry_level_specific - nullable string

因此,当您没有特定类型的列时,STI 将是合适的。但是您想在代码中添加特定行为。例如用户类型(管理员、作者)。

即便如此,这也是一个偏好问题。

【讨论】:

    【解决方案2】:

    这真的取决于你的员工对象的状态和行为。

    以下是我在做决定时会考虑的几点

    • 如果您的对象的状态/属性不同,那么您肯定会创建不同的模型,因为您的数据将存储在不同的表中。
    • 如果大多数状态/属性相同而有些不同,您可以 考虑将所有内容存储在一个表/模型中,并在 行为创建单独的表,如Ron Van Der Heijden 有 建议,您可以考虑使用该查询范围 与数据库的交易。

    另一个视图将是

    • 如果您将创建不同的表,您将创建多少个 JOIN, 这会影响性能和其他东西吗,它会让你的 代码复杂?
    • 你能建立更简单的关系并独立处理事情吗?
    • 当您制作 API 时,您的 代码使api过度工作?或者您需要创建太多请求 进行任何操作?

    这些东西将决定你将如何做出决定。

    更新 1: 关于您正在考虑使用的包,我想补充一点,考虑在表中使用父键,您可以在单个模型中定义关系。我认为您不需要使用包,您可以自己定义,我猜。

    【讨论】:

      【解决方案3】:

      我不明白您为什么不创建简单的一对多关系。根据您提供的信息,多态关系看起来没有必要。我认为正确的方法是创建employee_roles 表和关系。然后,您可以为不同的员工类型授予不同的权限。有几种方法可以做到这一点。您可以创建一个中间件来创建路由限制。您可以在控制器中执行功能之前检查角色,并仅在员工有权限时运行。您可以在刀片中使用 if-else 不渲染 auth 用户等无法使用的部分。

      【讨论】:

        【解决方案4】:

        如果您有不同“类型”的员工,并且每种员工类型应该有不同的逻辑,那么是的,这听起来像是一种多态关系。

        【讨论】:

          猜你喜欢
          • 2018-11-02
          • 2017-08-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-25
          • 1970-01-01
          • 2020-02-13
          • 1970-01-01
          • 2018-09-01
          相关资源
          最近更新 更多