hedronium/seed-cascade

基于范围的Laravel级联种子生成器。

v1.1.0 2016-11-26 14:34 UTC

This package is not auto-updated.

Last update: 2024-09-23 07:30:10 UTC


README

基于范围的Laravel级联种子生成器。

此软件包允许您通过指定类似1-10的数字范围以级联方式定义数据库种子。

文档

查看文档

简介

以下是您新的种子类的外观。

use Hedronium\SeedCascade\SeedCascade;

class DatabaseSeeder extends SeedCascade {
  public $table = "food";

  public function seedSheet() {
    return [
      '1-6' => [
        'name' => 'Cabbage',
        'type' => 'vegetable'
      ],
      '4-6' => [
        'name' => 'Carrot'
      ]
    ];
  }
}

food表中的插入数据

它在food表中插入6行,其中名称列在前面三行设置为"Cabbage",在后面三行设置为"Carrot"。

功能列表

  • 基于范围的种子
  • 重叠范围
  • 直接将数据插入到数据库中
  • 使用模型插入数据
  • 字段继承
  • 字符串插值
  • 闭包作为值源
  • 方法作为值源

入门

安装

通过composer安装。在您的Laravel项目目录中运行以下命令。

$ composer require hedronium/seed-cascade

Packagist上查看版本信息。

创建种子生成器

  1. 创建一个扩展
    Hedronium\SeedCascade\SeedCascade

  2. 添加$table$model公共属性。

  3. 实现一个返回种子定义的seedSheet()方法。

示例

use Hedronium\SeedCascade\SeedCascade;

class DatabaseSeeder extends SeedCascade {
  public $table = "fruits";

  public function seedSheet() {
    return [
      '1-10' => [
        'name' => 'Potao'
      ]
    ];
  }
}

种子定义包含在一个关联数组中。键作为种子数据的范围(例如,"1-10"表示插入的前10行),指向另一个包含键值对的关联数组。

使用模型

use Hedronium\SeedCascade\SeedCascade;
use App\Potato;

class DatabaseSeeder extends SeedCascade {
  public $model = Potato::class;

  public function seedSheet() {
    // Return seeding definitions.
  }
}

多个范围

也可以指定多个范围。

return [
    '1-10' => ['name' => 'Potato'],
    '11-20' => ['name' => 'Tomato']
]

重叠范围

重叠范围不仅可能,而且鼓励!

return [
    '1-10' => ['name' => 'Potato', color => 'yellow'],
    '6-10' => ['name' => 'Mango']
]

在重叠范围的情况下,属性会自动继承。这意味着从110的所有行都将具有color属性设置为yellow

运行种子生成器

与正常的Laravel种子生成器相同。

$ php artisan db:seed

看,这并不令人惊讶。

种子定义

SeedCascade比您上面看到的要酷得多。让我们开始利用它的真正潜力。

范围

xy

与上面一样。由连字符分隔的两个数字。

return [
    '1-5' => ['name' => 'Potatoes']
]

x开始

这种类型的范围允许您编写从某个点开始一直持续到永远的定义。

return [
    '3-n' => ['name' => 'Potatoes']
]

一个数字和字符n由连字符分隔。

实际上连字符后面的内容并不重要。这意味着,'3-Infinity''3-n''3-potato'甚至'3-'都完全一样。

警告:如果我们使用像上面这样的'到无限'的范围,我们绝对必须设置种子类中的$count属性,否则SeedCascade会非常生气!

class DatabaseSeeder extends SeedCascade
{
    public $count = 20;
    public $table = "edible_things";

    public function seedSheet()
    {
        return [
            '1-10' => ['name' => 'Potao'],
            '3-n' => ['name' => 'Tomato']
        ];
    }
}

这确保了种子生成器知道何时停止。

只有x

有时我们可能只想更改单行的值。为此,我们只需创建一个没有定义范围的键。

return [
    '1-10' => ['name' => 'Mango'],
    '3' => ['name' => 'Dragon Fruit']
]

只有插入的第三行将它的name字段设置为'Dragon Fruit'

直接值

这个很简单,我们只需输入值。

return [
    '1-n' => ['name' => 'Potato', 'price' => 20],
    '5-n' => ['name' => 'Potato', 'price' => 100]
]

数组

这个也很简单。我们以数组的形式输入多个值。

return [
  '1-4' => [
	'type' => 'fruit',
	'name' => $this->arr([
		'tomato',
		'mango',
		'lichee',
		'pineapple'
	])
  ]
]

如果范围大于数组元素的数量(如1-6),则返回null

还有一个可选的第二个参数。它被称为 $wrap。如果您将其设置为 true,则播种器将重新从开始处开始。

return [
  '1-5' => [
	'type' => 'fruit',
	'name' => $this->arr([
		'fruit X',
		'fruit Y'
	], true)
  ]
]

将导致

字符串插值

继承

当然,我们也可以只写一个平均字符串然后继续前进,但我们添加了一些额外的魔法以防万一。让我们从一个例子开始

return [
  '1-10' => ['name' => 'Potato', 'price' => 30],
  '5-10' => ['name' => 'Super {inherit}', 'price' => 100]
]

{inherit} 将被替换为 "Potato"。这意味着第 6 行到 5 10 的所有行将用它们的 name 字段中的 Super Potato 填充。

引用字段

如果我们想在其他字段中插值呢?SeedCascade 已为您覆盖了这一点!

return [
    '1-10' => [
        'name' => '{self.type} Engine ({self.model})',
        'type' => 'Jet',
        'model' => 'C3'
    ]
];

这将向数据库中插入 10 行,其中所有名称字段都是 Jet engine (C3)

当当前定义块实际上没有引用的特定属性时,此功能非常出色。例如

return [
    '1-10' => [
        'type' => 'Jet'
    ],
    '1-5' => [
        'name' => '{self.type} Fuel'
    ],
    '6-10' => [
        'name' => '{self.type} Engine'
    ]
];

记得“级联”部分吗?因此,现在我们将有 10 行在数据库中。前 5 行是 Jet Fuel,最后 5 行是 Jet Engine,所有这些都将有一个 typeJet

显式继承字段

想要确保从更高的范围获取值吗?看看

return [
  '1-10' => ['color' => 'Red'],
  '6-10' => [
    'name' => '{inherit.color} Flower',
    'color' => 'Yellow'
  ]
]

最后 5 行的名称将为 'Red Flower' NOT 'Yellow Flower'

迭代计数

您还可以使用 {i},它具有当前的迭代计数。

return [
    '1-5' => ['username' => 'user_{i}']
]

这将生成 5 行,用户名分别为: user_1user_2user_3user_4user_5

注意:迭代计数从 1 开始。

闭包

有时你需要更多的力量!也许是因为你贪婪? 开个玩笑。值也可以是闭包。

return [
    '1-10' => [
        'order' => function () {
            return rand(1, 100);
        }
    ]
];

这将插入 10 行,其中 order 的值是闭包返回的随机整数。

参数

闭包接收 3 个参数。

  • $i - 迭代计数。
  • $self - 一个对象,让您访问其他字段值。
  • $inherit - 一个对象,允许您继承字段值。

$i

$i 的使用很明显。这里是一个使用闭包的用户名示例

return [
    '1-5' => [
        'username' => function ($i) {
            return 'user_'.$i;
        }
    ]
];

$self

$self 对象实现了魔法方法,允许动态引用属性。

return [
    '1-3' => [
        'type' => 'admin'
        'username' => function ($i, $self) {
            return $self->type . '_' . $i;
        }
    ]
];

这将插入 3 行,用户名为 admin_1admin_2admin_3

$inherit

$inherit 对象可以像 $inherit() 一样调用,也可以连接或插值到字符串中,如 'super_'.$inherit"super_$inherit",所有这些都将得到相同的值。

return [
    '1-n' => [
        'price' => 10
    ],
    '6-10' => [
        'price' => function ($i, $self, $inherit) {
            return $inherit() * 2;
        }
    ]
];

最后 5 行的价格将是前 5 行的两倍。
另一方面,可以直接混合字符串,如下所示

return [
    '1-n' => [
        'type' => 'admin'
    ],
    '6-10' => [
        'type' => function ($i, $self, $inherit) {
            return "super_$inherit";
            // or
            return "super_".$inherit;
        }
    ]
];

也支持继承其他字段

return [
  '1-n' => [
    'username' => 'user_{i}'
  ],
  '6-10' => [
    'hash' => function ($i, $self, $inherit) {
      return md5($inherit->username);
    }
  ]
];

绑定闭包

想要引用种子类属性或调用种子类方法的闭包吗?查看 local(Closure $closure) 方法。

class DatabaseSeeder extends SeedCascade
{
  public $table = "magic";
  protected $meaning_of_life = 42;

  public function seedSheet()
  {
    return [
      '1-10' => [
        'lucky_number' => $this->local(function () {
          return $this->meaning_of_life * rand(1,10)
        })
      ]
    ];
  }
}

是的。在闭包中可以使用 $meaning_of_life。魔法。本地闭包也传递与普通闭包相同的参数:$i$self$inherit

使用方法

让我们将上面的示例转换为使用类方法。

class DatabaseSeeder extends SeedCascade
{
  public $table = "magic";
  protected $meaning_of_life = 42;

  protected function life() {
    return $this->meaning_of_life * rand(1, 10);
  }

  public function seedSheet()
  {
    return [
      '1-10' => [
        'lucky_number' => $this->method('life')
      ]
    ];
  }
}

构造函数 & Faker

SeedCascade 不介意您定义构造函数(或析构函数)。以下是一个使用 Faker 的示例。

class DatabaseSeeder extends SeedCascade
{
    public $table = "people";
    protected $faker = null;

    public function __construct()
    {
        $this->faker = new Faker;
    }

    public function seedSheet()
    {
        return [
            '1-10' => [
                'name' => $this->local(function () {
                    return $this->faker->name;
                })
            ]
        ];
    }
}

评估顺序

SeedCascade 将从最具体的范围开始评估。这意味着 1-10 将先于 1-201-Infinity 进行评估。

继承也将取决于此。如果您在 1-10 范围内使用 {inherit},则插值的值将从 1-20 范围中解析。如果父范围没有属性,它将回溯到找到定义属性的最大范围。

如果没有更高的范围定义 {inherit} 属性,则 {inherit} 将成为 null