【问题标题】:Laravel Eloquent collection of mixed modelsLaravel Eloquent 混合模型集合
【发布时间】:2019-11-10 12:27:15
【问题描述】:

我有一个数据库,其中有一个名为 files 的表。其中,我们有以下结构 -

- id
- parent_id (nullable)
- name
- type (enum: File or Folder)
- created_at
- updated_at

然后我有两个模型,一个叫File,一个叫FolderFolder 扩展 File。例如,当我调用File::all(), 时,有没有一种方法可以利用 Eloquent 根据数据库type 字段映射相应的模型?

【问题讨论】:

  • 您的意思是要对文件和文件夹进行排序,以便文件嵌套在它们所属的文件夹下吗?
  • 对不起,我的错。意识到您真正想要的是按类型填充它们。

标签: laravel eloquent laravel-6


【解决方案1】:

Eloquent 返回集合实例,因此一种方法是调用 map() 并让它为每个项目返回适当的对象,例如,如果它是一个文件,则只返回该文件,而如果它是一个文件夹,则填充一个新的 @987654322 @instance 并返回它。

或者您可以让 FileFolder 成为在同一个表上工作的模型,使用全局范围来限制按类型设置的查询,然后在它们上调用 all() 并合并它们。

但我认为最好的办法是让它们成为一个单一的模型,根据类型的不同表现不同。在模型上的方法中放置任何不同的功能,以便通过调用这些方法无论类型如何,都可以对其进行相同的处理。我认为这是更安全的选择,因为您使模型具有多态性 - 无论类型如何,它们都可以被同等对待。

【讨论】:

  • 感谢 Matthew 的回答,与此同时,我找到了一个对我很有效的解决方案!
【解决方案2】:

我已经能够通过扩展 Laravel Models newFromBuilder 方法来找出答案。

这是我的课 -

class File {

    public static $types = ['File', 'Folder'];

     /**
     * Create a new model instance that is existing.
     *
     * @param array $attributes
     * @param null  $connection
     *
     * @return Model|string
     */
    public function newFromBuilder($attributes = [], $connection = null)
    {
        $model = $this->newInstanceFromType($attributes->type);

        $model->exists = true;

        $model->setRawAttributes((array) $attributes, true);

        $model->setConnection($connection ?: $this->getConnectionName());

        $model->fireModelEvent('retrieved', false);

        return $model;
    }

    /**
     * Determine our model instance based on the type field.
     *
     * @param string $type
     *
     * @return mixed
     */
    private function newInstanceFromType(string $type)
    {
        if (!in_array($type, static::$types)) {
            throw new InvalidArgumentException('$type must be one of static::$types');
        }

        $model = 'App\Models\\' . $type;
        return new $model;
    }
}

这将返回 FileFolder 模型实例,具体取决于数据库中的 type 枚举。

感谢大家的意见!

【讨论】:

    猜你喜欢
    • 2019-09-08
    • 1970-01-01
    • 2019-10-13
    • 2017-04-29
    • 1970-01-01
    • 2019-05-19
    • 2018-11-11
    • 1970-01-01
    • 2015-06-06
    相关资源
    最近更新 更多