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)
];