【问题标题】:Find Eloquent Class by Table Name按表名查找 Eloquent 类
【发布时间】:2022-01-06 17:41:39
【问题描述】:

我目前正在围绕旧数据库包装 Laravel/Eloquent 并建立关系,但是我遇到了一些现有系统的动态特性的问题。一些关系是在数据库本身中定义的,这意味着table_a 中的项目可以与任意数量的其他表相关,具体取决于存储的指令。

这包括存储在指令中的表名。

我当前的目标是找到为表 X 构建的 Eloquent Model 类。

一些注意事项:

  • 为了向后兼容,我无法将现有的数据库条目更改为存储类而不是表名。
  • 因为我们的表名不符合 Laravel 的命名约定,所以我不能根据表名假设类名。
  • 该数据库有超过 300 个表和超过 100 个当前用于映射指令的表,所以当 Eloquent 模型已经在 $table 属性中维护它时,我更喜欢不需要大量类表映射列表的动态解决方案。

也许我只是希望 Laravel 将所有 Eloquent 类的清单保存在我可以利用的内存中,但这可能是一厢情愿的想法。

有什么聪明的想法吗?

【问题讨论】:

  • 您的问题太宽泛,无法回答。你是说要使用表名而不是类名来识别多态关系?
  • 其驱动力是建立多态关系,但问题更笼统:我有表名,我需要弄清楚为它们构建了哪些模型类。我希望有一个解决方案可以利用这些类已经具有 $table 属性和必要信息的事实。
  • 您希望找到解决方案,但您还没有清楚地阐明问题所在。 laravel.com/docs/8.x/…
  • 问题是我有一个表名列表,我需要确定为它们构建了哪些 Eloquent 模型,我正在寻找一种不依赖显式映射的动态方法来实现这一点可能维护不善的表。这就是问题所在,正如我现在简单而简洁地说过几次的那样。我打算对这些类做什么最终超出了所述问题的范围。
  • 我建议你从 PHP 的 Reflection 类开始。您应该能够获取每个模型类的 $table 属性的值。 php.net/reflection

标签: laravel eloquent


【解决方案1】:

查看反射,根据 miken32 的建议,我能够编译示例的 sn-ps 并将功能添加到 BaseModel 类。这可能不是我的最终实现,但它让我得到了我需要的东西。

<?php

namespace App\Models;

use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;

abstract class BaseModel extends Model
{
    public static function tableName(): string
    {
        return with(new static)->getTable();
    }

    public static function getClassMetadata(): Collection
    {
        return Cache::rememberForever('model:eloquent:metadata',function(){
            return collect(File::allFiles(app_path()))->map(function ($item){
                $path = $item->getRelativePathName();
                return sprintf('\%s%s', Container::getInstance()->getNamespace(),
                    strtr(substr($path, 0, strrpos($path, '.')), '/', '\\'));
            })->filter(function ($class){
                $valid = false;
                if (class_exists($class)) {
                    $reflection = new \ReflectionClass($class);
                    $valid = $reflection->isSubclassOf(BaseModel::class) && !$reflection->isAbstract();
                }
                return $valid;
            })->map(function ($class){
                $reflection = new \ReflectionClass($class);
                return [
                    'fqcn' => $class,
                    'table' => $reflection->getMethod('tableName')->invoke(null)
                ];
            })->values();
        });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 2021-03-05
    • 2023-01-03
    • 2012-07-02
    相关资源
    最近更新 更多