我无法找到在创建工厂和播种机时如何管理外键。
我有一张users桌子和一张blog_posts桌子。该blog_posts表有一个user_id引用 的外键users.id。我想在我的数据库中添加用户和博客文章。
我已经了解了如何使用以下内容为每个种子博客文章创建新用户:
/**
* Define the BlogPost model's default state.
*
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'created_at' => now(),
'updated_at' => now(),
'title' => $this->faker->words(5, true),
'body' => $this->faker->paragraphs(6, true)
];
}
Run Code Online (Sandbox Code Playgroud)
...但我想引用现有用户,因为我正在像这样执行数据库种子:
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call([
UsersTableSeeder::class,
BlogPostsTableSeeder::class
]);
}
Run Code Online (Sandbox Code Playgroud) 在 Laravel 8 中,可以快速填充与工厂的关系。但是,我不知道如何生成多个关系。如何使用新的 Laravel 8 语法为每个链接创建随机或新的关系?
此工厂语法仅在 Laravel 8 中可用。 https://laravel.com/docs/8.x/database-testing#factory-relationships
考虑以下关系:
<?php
class Post extends Model
{
use HasFactory;
function links()
{
return $this->hasMany(Link::class);
}
}
class Website extends Model
{
use HasFactory;
function links()
{
return $this->hasMany(Link::class);
}
}
class Link extends Model
{
use HasFactory;
function post()
{
return $this->belongsTo(Post::class);
}
function website()
{
return $this->belongsTo(Website::class);
}
}
Run Code Online (Sandbox Code Playgroud)
我下面尝试的只会为所有链接生成一个模型。如何使用新的 Laravel 8 语法为每个链接创建随机或新的关系?
Link::factory()->count(3)->forPost()->forWebsite()->make()
=> Illuminate\Database\Eloquent\Collection {#4354
all: [
App\Models\Link {#4366 …Run Code Online (Sandbox Code Playgroud) 我想问如何让faker产生独特的价值?
我知道这实际上是一个熟悉的问题,您可能会放置一些重复的链接,例如链接 1、链接 2,但不幸的是,这些链接不能回答我的问题。
下面是我的代码。我尝试过unique(true)但结果相同。
return [
'user_id' => $this->faker->unique()->numberBetween(1, 10),
//more code here
];
Run Code Online (Sandbox Code Playgroud)
下面是我得到的结果。正如您所看到的,插入了很多重复的“5”。
我正在使用 Laravel 8 开发一个 Web 应用程序。我注意到 Laravel 8 中发生了很多变化,包括工厂。
我的 MenuCategory 模型类有一个工厂类 MenuCategoryFactory ,其定义如下。
<?php
namespace Database\Factories;
use App\Models\Menu;
use App\Models\MenuCategory;
use Illuminate\Database\Eloquent\Factories\Factory;
class MenuCategoryFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = MenuCategory::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
'menu_id' => Menu::factory()->create(),
];
}
}
Run Code Online (Sandbox Code Playgroud)
在我的代码(数据库播种器类)中,我在创建工厂时尝试按如下方式覆盖 menu_id 。
$restaurant = Restaurant::first();
MenuCategory::factory()->create([ …Run Code Online (Sandbox Code Playgroud) 我使用以下代码创建 20 个帖子,每个帖子有 3 条评论。
Post::factory()
->times(20)
->has(Comment::factory()->times(3))
->create()
Run Code Online (Sandbox Code Playgroud)
相反,我想创建 20 个帖子,每个帖子都有随机数量的评论(例如帖子 1 有 2 条评论,帖子 2 有 4 条评论等)
这不起作用,每个帖子都有相同(随机)数量的评论。
Post::factory()
->times(20)
->has(Comment::factory()->times(rand(1, 5)))
->create()
Run Code Online (Sandbox Code Playgroud)
我怎样才能实现这个目标?
当尝试在 laravel 8 中运行工厂时,我收到此错误。我已经查看了几篇有关此错误的帖子,但它们似乎都来自直接错误地保存/创建。不使用工厂。所以我不确定为什么工厂没有正确保存它。
\n我的迁移有:
\npublic function up()\n{\n Schema::create('posts', function (Blueprint $table) {\n $table->id();\n $table->string('slug');\n $table->string('name');\n $table->longText('desc');\n $table->foreignId('user_id')->constrained();\n $table->timestamps();\n $table->softDeletes();\n });\n}\nRun Code Online (Sandbox Code Playgroud)\n我的模型有:
\nclass Post extends Model\n{\n use HasFactory, SoftDeletes;\n\n public function user()\n {\n return $this->belongsTo(User::class);\n }\n\n public function setSlugAttribute($value)\n {\n $this->attributes['slug'] = Str::slug($this->name);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n我厂有:
\npublic function definition()\n{\n return [\n 'name' => $this->faker->words,\n 'desc' => $this->faker->sentence,\n 'user_id' => rand(1,10)\n ];\n}\nRun Code Online (Sandbox Code Playgroud)\n我的帖子播种机有:
\npublic function run()\n{\n Post::factory()->times(13)->create();\n}\nRun Code Online (Sandbox Code Playgroud)\n我的主要 DatabaseSeeder 运行一个用户播种器,可播种 10 个用户。然后一个帖子播种者播种了 13 …
是否可以将数据从播种机传递到工厂?
这是我的PictureFactory:
class PictureFactory extends Factory{
protected $model = Picture::class;
public function definition($galleryId = null, $news = false){
if (!is_null($galleryId)){
$galley = Gallery::find($galleryId);
$path = 'public/galleries/' . $galley->name;
$newsId = null;
}
if ($news){
$path = 'public/newsPicture';
$newsId = News::all()->random(1);
}
$pictureName = Faker::word().'.jpg';
return [
'userId' => 1,
'src' =>$this->faker->image($path,400,300, 2, false) ,
'originalName' => $pictureName,
'newsId' => $newsId
];
}
}
Run Code Online (Sandbox Code Playgroud)
我在数据库播种器中像这样使用它:
News::factory(3)
->has(Comment::factory()->count(2), 'comments')
->create()
->each(function($news) {
$news->pictures()->save(Picture::factory(null, true)->count(3));
});
Run Code Online (Sandbox Code Playgroud)
但$galleryId和$news不传递到 …
在 Laravel 8.12 从控制器运行工厂时出现错误:
[2021-01-12 16:42:10] local.ERROR: array_merge(): Expected parameter 2 to be an array, int given {"exception":"[object] (ErrorException(code: 0): array_merge(): Expected parameter 2 to be an array, int given at /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:381)
[stacktrace]
#0 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php(381): array_merge()
#2 [internal function]: Illuminate\\Database\\Eloquent\\Factories\\Factory->Illuminate\\Database\\Eloquent\\Factories\\{closure}()
#3 /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(884): array_reduce()
Run Code Online (Sandbox Code Playgroud)
...在我运行的控制器中:
Ad::addDummyData();
Run Code Online (Sandbox Code Playgroud)
在应用程序/模型/Ad.php 中:
公共静态函数 addDummyData() {
$ads = Ad::factory()->create(10); // POINTS TO THIS LINE
\Log::info( varDump($ads, ' -1 addDummyData() $ads::') );
Run Code Online (Sandbox Code Playgroud)
}
在数据库/工厂/AdFactory.php 中:
<?php
namespace Database\Factories;
use Config;
use App\Models\Ad;
use …Run Code Online (Sandbox Code Playgroud) 在 laravel 8 应用程序中,我使用工厂为广告表添加虚拟数据:
$ads = Ad::factory()->count(10)->expired($year, $month)->create([
]);
Run Code Online (Sandbox Code Playgroud)
以及数据库/工厂/AdFactory.php:
<?php
namespace Database\Factories;
use Config;
use Carbon\Carbon;
use App\Models\Ad;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use \Cviebrock\EloquentSluggable\Services\SlugService;
class AdFactory extends Factory
{
protected $model = Ad::class;
public function definition()
{
$text= $this->faker->text;
$slugValue = SlugService::createSlug(Ad::class, 'slug', $text);
return [
'title' => $text,
'ad_token' => $text,
'slug' => $slugValue,
'phone_display' => (rand(1, 3) == 1),
'has_locations' => (rand(1, 4) == 1),
'status' => 'A',
'price' => mt_rand(10, 500),
'ad_type' => (rand(1, 2) == …Run Code Online (Sandbox Code Playgroud) 我开始使用 Laravel 8 构建一个 Web 应用程序。我注意到 Laravel 8 中发生了一些变化,包括模型工厂。现在,我正在使用模型工厂编写单元测试。但是当我使用 faker 伪造字段时,它会抛出错误。
这是我的测试方法。
public function testHasRoleReturnsTrue()
{
$user = User::factory()->create();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我现在要做的就是尝试使用 factory 创建用户。这是我的用户模型工厂类。
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
'email' => …Run Code Online (Sandbox Code Playgroud)