Laravel 5.8 - 播种多对一关系
Laravel 5.8 - Seeding a ManyToOne relationship
大家晚上好,
我期待在我的 类别 Table[=96= 中播种我的 Post Table ] 通过外键 category_id,在我的 Post Table.
中
但不幸的是我遇到了一个我无法处理的问题,这就是我请求你帮助的原因
这是我的模型 :
Post :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
/**
* @method static create(array $array)
*/
class Post extends Model
{
use SoftDeletes;
protected $fillable = ['title', 'description', 'contenu', 'image', 'published_at', 'category_id'];
/**
* Delete image from storage
*/
public function deleteImage()
{
Storage::delete($this->image);
}
// OneToMany(Inverse)
public function category()
{
return $this->belongsTo(Category::class, 'category_id', 'id');
}
// ManyToMany
public function tags()
{
return $this->belongsToMany(Tag::class);
}
/**
* Check if a post has tag.
* tags return a collection, if we want to get the id from the array
* we must use the pluck function
* @param $id
* @return bool
*/
public function hasTag($id)
{
return in_array($id, $this->tags->pluck('id')->toArray());
}
}
类别
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* @method static create(array $all)
*/
class Category extends Model
{
protected $fillable = ['name'];
// OneToMany
public function posts()
{
return $this->hasMany(Post::class);
}
}
这是我的工厂 :
Post
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Category;
use App\Post;
use Carbon\Carbon;
use Faker\Generator as Faker;
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
$factory->define(Post::class, function (Faker $faker) {
$image = $faker->image();
$imageFile = new File($image);
return [
'title' => 'hello',
'description' => $faker->text(100),
'contenu' => $faker->text(100),
'image' => Storage::disk('public')->putFile('posts', $imageFile),
'published_at' => $faker->date('Y-m-d'),
'category_id' => factory('App\Category')->create()->id,
// 'category_id' => $faker->numberBetween(1,5)
];
});
类别
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Category;
use Faker\Generator as Faker;
$factory->define(Category::class, function (Faker $faker) {
return [
'name' => $faker->words(5, true),
'image' => $faker->imageUrl()
];
});
我的播种机
<?php
use App\Post;
use App\Tag;
use Illuminate\Database\Seeder;
class PostTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
/**
* MANY TO MANY
*/
$posts = factory(Post::class, 15)->create(); // 1.
$tags = factory(Tag::class, 10)->create(); // 2
$posts
->each(function (Post $posts) use ($tags) {
$posts->tags()->attach(
$tags->random(rand(1, 10))->pluck('id')->toArray() // 3.
);
});
}
}
我知道通过 hasMany 关系,你可以这样做:
factory(User::class, 10)->create()->each(function ($user) {
$user->posts()->saveMany(factory(Posts::class, 5)->make());
});
或者这样:
//create 10 users
factory(User::class, 10)->create()->each(function ($user) {
//create 5 posts for each user
factory(Post::class, 5)->create(['user_id'=>$user->id]);
});
有一个用户和一个 Post 模型相互连接:Laravel - Seeding Relationships
我也知道,如果你加上这个:
'category_id' => factory('App\Category')->create()->id,
到你的工厂,它将根据你要求的帖子数量生成 category_id 个字段。
所以这意味着如果您请求 5 个帖子,它将为您生成从 1 到 5 的 5 个 category_id 数字:这也意味着您的数据库中有 5 个新类别。
那么如果你请求 50 个帖子,你将获得 50 个新类别..
这不是我要找的。
所以我的问题是,
我怎样才能做到这一点,我可以添加我想要的类别的 所需 编号,以及 所需 编号我想要哪些帖子?
这样两个表在数据库中仍然链接在一起。
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('category_id');
$table
->foreign('category_id')
->references('id')
->on('categories')
->onDelete('cascade');
如果您查看我的 Post 工厂,您会看到以下评论:
// 'category_id' => $faker->numberBetween(1,5)
我知道通过这种方式,通过生成一个随机数,最大值等于我想要的类别数:
factory(Category::class, 5)->create();
它将为我的 category_id 提供一个 1 到 5 之间的随机数,同时,为我提供我想要的类别数。
所以我的帖子不会有线性 category_id (1,2,3,4,5),但会随机排列。
这也是我正在寻找的。
有更好的方法吗?
我想您已经找到了自己问题的答案。我只想创建您想要的 Category 对象的数量(比如 5)。先做这个。
factory(Category::class, 5)->create();
现在你已经有了这些,如果这是你的第一次迁移,你可以像在你的 Post 工厂模型中那样随机添加它们:
return [
'title' => 'hello',
// .. etc.
'category_id' => $faker->numberBetween(1,5)
];
但是,如果您已经有了 Category id 的值,或者您可以稍后添加或更改它们,并希望为将来使用工厂 Posts在原来的迁移之外,可以得到当前的category ids然后随机注入到同一个factory中的postcategory_id
字段:
$cat_ids = Category::pluck('id', 'id')->toArray();
return [
'title' => 'hello',
// .. etc.
'category_id' => array_rand($cat_ids, 1)
];
大家晚上好,
我期待在我的 类别 Table[=96= 中播种我的 Post Table ] 通过外键 category_id,在我的 Post Table.
中但不幸的是我遇到了一个我无法处理的问题,这就是我请求你帮助的原因
这是我的模型 :
Post :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
/**
* @method static create(array $array)
*/
class Post extends Model
{
use SoftDeletes;
protected $fillable = ['title', 'description', 'contenu', 'image', 'published_at', 'category_id'];
/**
* Delete image from storage
*/
public function deleteImage()
{
Storage::delete($this->image);
}
// OneToMany(Inverse)
public function category()
{
return $this->belongsTo(Category::class, 'category_id', 'id');
}
// ManyToMany
public function tags()
{
return $this->belongsToMany(Tag::class);
}
/**
* Check if a post has tag.
* tags return a collection, if we want to get the id from the array
* we must use the pluck function
* @param $id
* @return bool
*/
public function hasTag($id)
{
return in_array($id, $this->tags->pluck('id')->toArray());
}
}
类别
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* @method static create(array $all)
*/
class Category extends Model
{
protected $fillable = ['name'];
// OneToMany
public function posts()
{
return $this->hasMany(Post::class);
}
}
这是我的工厂 :
Post
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Category;
use App\Post;
use Carbon\Carbon;
use Faker\Generator as Faker;
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
$factory->define(Post::class, function (Faker $faker) {
$image = $faker->image();
$imageFile = new File($image);
return [
'title' => 'hello',
'description' => $faker->text(100),
'contenu' => $faker->text(100),
'image' => Storage::disk('public')->putFile('posts', $imageFile),
'published_at' => $faker->date('Y-m-d'),
'category_id' => factory('App\Category')->create()->id,
// 'category_id' => $faker->numberBetween(1,5)
];
});
类别
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Category;
use Faker\Generator as Faker;
$factory->define(Category::class, function (Faker $faker) {
return [
'name' => $faker->words(5, true),
'image' => $faker->imageUrl()
];
});
我的播种机
<?php
use App\Post;
use App\Tag;
use Illuminate\Database\Seeder;
class PostTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
/**
* MANY TO MANY
*/
$posts = factory(Post::class, 15)->create(); // 1.
$tags = factory(Tag::class, 10)->create(); // 2
$posts
->each(function (Post $posts) use ($tags) {
$posts->tags()->attach(
$tags->random(rand(1, 10))->pluck('id')->toArray() // 3.
);
});
}
}
我知道通过 hasMany 关系,你可以这样做:
factory(User::class, 10)->create()->each(function ($user) {
$user->posts()->saveMany(factory(Posts::class, 5)->make());
});
或者这样:
//create 10 users
factory(User::class, 10)->create()->each(function ($user) {
//create 5 posts for each user
factory(Post::class, 5)->create(['user_id'=>$user->id]);
});
有一个用户和一个 Post 模型相互连接:Laravel - Seeding Relationships
我也知道,如果你加上这个:
'category_id' => factory('App\Category')->create()->id,
到你的工厂,它将根据你要求的帖子数量生成 category_id 个字段。
所以这意味着如果您请求 5 个帖子,它将为您生成从 1 到 5 的 5 个 category_id 数字:这也意味着您的数据库中有 5 个新类别。
那么如果你请求 50 个帖子,你将获得 50 个新类别..
这不是我要找的。
所以我的问题是,
我怎样才能做到这一点,我可以添加我想要的类别的 所需 编号,以及 所需 编号我想要哪些帖子?
这样两个表在数据库中仍然链接在一起。
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('category_id');
$table
->foreign('category_id')
->references('id')
->on('categories')
->onDelete('cascade');
如果您查看我的 Post 工厂,您会看到以下评论:
// 'category_id' => $faker->numberBetween(1,5)
我知道通过这种方式,通过生成一个随机数,最大值等于我想要的类别数:
factory(Category::class, 5)->create();
它将为我的 category_id 提供一个 1 到 5 之间的随机数,同时,为我提供我想要的类别数。
所以我的帖子不会有线性 category_id (1,2,3,4,5),但会随机排列。
这也是我正在寻找的。
有更好的方法吗?
我想您已经找到了自己问题的答案。我只想创建您想要的 Category 对象的数量(比如 5)。先做这个。
factory(Category::class, 5)->create();
现在你已经有了这些,如果这是你的第一次迁移,你可以像在你的 Post 工厂模型中那样随机添加它们:
return [
'title' => 'hello',
// .. etc.
'category_id' => $faker->numberBetween(1,5)
];
但是,如果您已经有了 Category id 的值,或者您可以稍后添加或更改它们,并希望为将来使用工厂 Posts在原来的迁移之外,可以得到当前的category ids然后随机注入到同一个factory中的postcategory_id
字段:
$cat_ids = Category::pluck('id', 'id')->toArray();
return [
'title' => 'hello',
// .. etc.
'category_id' => array_rand($cat_ids, 1)
];