zhangyu0310/eloquent-model-generator

Eloquent 模型生成器

1.3.8 2021-04-29 05:41 UTC

This package is auto-updated.

Last update: 2024-09-29 06:02:58 UTC


README

Eloquent 模型生成器是基于 Code Generator 的工具,用于生成 Eloquent 模型。

说明

此仓库是从原始开发者那里fork的,基于版本1.3.7。

由于开发过程中遇到了一些小问题,对源代码进行了少量修改。

修改如下:

  1. 工具默认会忽略表的主键,不会将其添加到$fillable字段中。(原因应该是大部分使用者的数据库主键是自增的)

在我的项目中,这个字段不是自增的,如果不将主键添加到$fillable中,就无法使用fill($request->all())等方法直接填充。

解决方案:

我增加了一个参数 --pk-fillable(主键可填充),是一个VALUE_NONE。指定了此参数后,主键也会添加到$fillable中。

  1. 在检查外键关系时,工具会扫描其他表(除table-name指定的表之外的其他表)。

在这种情况下,如果其他表中的列有一些非常特殊的类型,例如bit类型,程序就会抛出异常,无法正常工作。我发现这个问题是因为这里使用了Liquibase生成数据库表,而Liquibase会生成一张名为databasechangeloglock的表:

CREATE TABLE `databasechangeloglock` (
  `ID` int(11) NOT NULL,
  `LOCKED` bit(1) NOT NULL,
  `LOCKGRANTED` datetime DEFAULT NULL,
  `LOCKEDBY` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

根本原因是调用DBALlistTables()时,对不支持的类型(bit类型)抛出了异常。

解决方案:

我这里的解决方案比较简单直接,仅适用于没有使用外键的业务。(从一个前数据库开发人员的角度来说,外键最好不用,效率很低,而且很多分布式数据库不支持外键)

--ignore-fk(忽略外键),是一个VALUE_NONE。指定了此参数后,工具将跳过外键关系的检查。

  1. 这可以算是一点小特性。生成的模型,其头部会有字段的说明。我在这个说明后面添加了数据库表列上的COMMENT。会生成类似这样的模型文件:
/**
 * @property integer $ServerID // 服务器ID
 * @property string $Name // 服务器名称
 * @property string $IP // IP地址
 * @property int $Port // 端口号
 */

不过这个功能需要配合我Git下的 Code Generator 仓库里的代码生成器使用。(也修改了一点点内容)

安装

步骤 1. 将 Eloquent 模型生成器添加到您的项目中

composer require krlove/eloquent-model-generator --dev

步骤 2. 注册 GeneratorServiceProvider

'providers' => [
    // ...
    Krlove\EloquentModelGenerator\Provider\GeneratorServiceProvider::class,
];

如果您使用的是 Laravel 5.5 或更高版本,则可以省略此步骤,因为此项目支持 Package Discovery 功能。

步骤 3. 配置您的数据库连接。

用法

使用

php artisan krlove:generate:model User

来生成模型类。生成器将查找名称为 users 的表,并为其生成一个模型。

table-name

使用 table-name 选项指定另一个表名

php artisan krlove:generate:model User --table-name=user

在这种情况下,生成的模型将包含 protected $table = 'user' 属性。

output-path

生成的文件将保存在您的应用程序的 app 目录中,并默认使用 App 命名空间。如果您想更改目的地和命名空间,请分别提供 output-pathnamespace 选项

php artisan krlove:generate:model User --output-path=/full/path/to/output/directory --namespace=Some\\Other\\NSpace

output-path 可以是绝对路径,也可以是相对于项目 app 目录的相对路径。绝对路径必须以 / 开头

  • /var/www/html/app/Models - 绝对路径
  • Models - 相对路径,将被转换为 /var/www/html/app/Models(假设您的项目应用程序目录为 /var/www/html/app

base-class-name

默认情况下,生成的类将从 Illuminate\Database\Eloquent\Model 扩展。要更改基类,请指定 base-class-name 选项

php artisan krlove:generate:model User --base-class-name=Some\\Other\\Base\\Model

backup

在生成新模型之前保存现有模型

php artisan krlove:generate:model User --backup

如果 User.php 文件已存在,它将首先被重命名为 User.php~ 并保存在同一目录中。然后,将生成一个新的 User.php

其他选项

有几个有用的选项可以用于定义多个模型属性

  • no-timestamps - 向模型添加 public $timestamps = false; 属性
  • date-format - 指定模型的 dateFormat 属性
  • connection - 指定模型的连接名称属性

全局覆盖默认选项

您不需要每次在执行命令时指定选项,您可以在项目的 config 目录中创建一个名为 eloquent_model_generator.php 的配置文件,并使用自己的默认值。生成器已经在 Resources/config.php 中包含了自己的配置文件,以下是一些选项

<?php

return [
    'namespace'       => 'App',
    'base_class_name' => \Illuminate\Database\Eloquent\Model::class,
    'output_path'     => null,
    'no_timestamps'   => null,
    'date_format'     => null,
    'connection'      => null,
    'backup'          => null,
];

您可以通过在 eloquent_model_generator.php 中定义 model_defaults 数组来覆盖它们

<?php

return [
    'model_defaults' => [
        'namespace'       => 'Some\\Other\\Namespace',
        'base_class_name' => 'Some\\Other\\ClassName',
        'output_path'     => '/full/path/to/output/directory',
        'no_timestamps'   => true,
        'date_format'     => 'U',
        'connection'      => 'other-connection',
        'backup'          => true,
    ],
];

注册自定义数据库类型

如果运行命令导致错误

[Doctrine\DBAL\DBALException]
Unknown database type <ANY_TYPE> requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.

这意味着您必须使用Doctrine注册您的类型 <ANY_TYPE>

例如,您将要注册 enum 类型,并希望Doctrine将其视为 string 类型(您可以在这里找到所有现有的Doctrine类型)。在您的 config/eloquent_model_generator.php 文件中添加以下行:

return [
    // ...
    'db_types' => [
        'enum' => 'string',
    ],
];

使用示例

user

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `email` varchar(100) NOT NULL,
  `role_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `role_id` (`role_id`),
  CONSTRAINT `user_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

命令

php artisan krlove:generate:model User  --table-name=user

结果

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

/**
 * @property int $id
 * @property int $role_id
 * @property mixed $username
 * @property mixed $email
 * @property Role $role
 * @property Article[] $articles
 * @property Comment[] $comments
 */
class User extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'user';

    /**
     * @var array
     */
    protected $fillable = ['role_id', 'username', 'email'];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function role()
    {
        return $this->belongsTo('Role');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function articles()
    {
        return $this->hasMany('Article');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function comments()
    {
        return $this->hasMany('Comment');
    }
}