hedronium / seed-cascade
基于范围的Laravel级联种子生成器。
Requires
- illuminate/database: >=4.2
Requires (Dev)
- phpunit/phpunit: 5.4.*
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上查看版本信息。
创建种子生成器
-
创建一个扩展
Hedronium\SeedCascade\SeedCascade
-
添加
$table
或$model
公共属性。 -
实现一个返回种子定义的
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'] ]
在重叠范围的情况下,属性会自动继承。这意味着从1到10的所有行都将具有color
属性设置为yellow
。
运行种子生成器
与正常的Laravel种子生成器相同。
$ php artisan db:seed
看,这并不令人惊讶。
种子定义
SeedCascade比您上面看到的要酷得多。让我们开始利用它的真正潜力。
范围
从x
到y
与上面一样。由连字符分隔的两个数字。
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
,所有这些都将有一个 type
为 Jet
。
显式继承字段
想要确保从更高的范围获取值吗?看看
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_1
、user_2
、user_3
、user_4
、user_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_1
、admin_2
、admin_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-20
或 1-Infinity
进行评估。
继承也将取决于此。如果您在 1-10
范围内使用 {inherit}
,则插值的值将从 1-20
范围中解析。如果父范围没有属性,它将回溯到找到定义属性的最大范围。
如果没有更高的范围定义 {inherit}
属性,则 {inherit}
将成为 null
。