Laravel Eloquent-种子文件中的For循环以一种奇怪的方式运行

时间:2019-04-17 18:18:24

标签: laravel

我有两个模型,article和project。一个项目可以有很多相关的文章,而一个文章可以属于一个项目,也可以不属于一个项目。我有两个播种者projectseeder和articleseeder。首先调用article seeder并运行正常,然后尝试在项目seeder中运行for循环以关联一些随机文章,结果是仅将一个文章添加到集合中。奇怪的是,所添加的文章与项目具有相同的ID,即,如果项目ID为1,则相关的文章ID也为1。我不知道为什么项目播种器内的for循环无法按预期工作。 / p>

   class Article extends Model{
    //An Article can only belong to one project or it could be independent of project
    public function project()
    {
        return $this->belongsToMany('App\Models\Project', 'id');
    }
class Project extends Model
{

    public function articles()
    {
        return $this->hasMany('App\Models\Article', 'id', 'id');
    }
}

还有我的工厂和播种机

$factory->define(Article::class, function (Faker $faker) {
    return [
        'title'         => $faker->sentence(rand(1,2)),
        'short_text'    => $faker->sentence(rand(3,5)),
        'content'       => $faker->paragraph(10),
        'is_featured'   => $faker->randomElement(['Y','N']),
        'posted_by'     =>'John Smith'

    ];
});


class ProjectTableSeeder extends Seeder
{
    public function run()
    {

        Eloquent::unguard();

        //select  random articles for project
        factory(App\Models\Project::class, 10)->create()
            ->each(function($project){
                //associate 3 random article with this project
                for ($i=0; $i <4 ; $i++) {
                    $project->articles->add(Article::find(rand(1,50))->get());
                }//end for
        }//end each function
        );


        Eloquent::reguard();

    }
}

我死掉了关系,但只得到了一篇文章。请帮助我找出我做错了!预先感谢您的帮助。

更新#1: 这些是模型的迁移文件

Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
            $table->string('title');
            $table->text('short_text'); // Mandetory first 150 chars of content
            $table->text('content');
            $table->char('is_featured'); // Y for N for No
            $table->string('posted_by'); // Auth user
        });

Schema::create('projects', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
            $table->text('title');
        });

更新#2:

非常感谢您的回答。我很惊讶您实际上创建了一个整个项目来回答我的问题!!!您真好,我非常感谢您的精神。您的解决方案就像魅力一样。

我不知道它是否会要求太多,但这是我想要的最后一个帮助。 所有10个项目都有相同的相关文章,即从第0条到第5条。我想选择随机的文章,而不是所有具有相同文章的项目。

UPDATE#3 我想出了另一种方法,并更改了工厂方法

    $factory->define(Article::class, function (Faker $faker) {
    return [
        'title'         => $faker->sentence(rand(1,2)),
        'short_text'    => $faker->sentence(rand(3,5)),
        'content'       => $faker->paragraph(10),
        'is_featured'   => $faker->randomElement(['Y','N']),
        'posted_by'     =>'John Smith',
        'project_id'    =>$faker->randomElement([null,rand(1,10)]),
    ];
});

现在,项目的项目ID为null或随机ID,因为项目ID和项目现在自动与项目相关。尽管如此,还是感谢您的宝贵时间。祝你有美好的一天。

1 个答案:

答案 0 :(得分:0)

首次发布答案。 :)

您的article()关系正在使用两个表中的id列来获取文章。这将导致您仅检索一篇文章。如果您在“文章”表中添加“ projects_id”列,并将该列设置为项目的ID,然后修改您的关系以使用该列,则可以获取多篇文章。

希望这会有所帮助。

更新: 在迁移列中添加-> nullable()可以将其保留为空或将其设置为特定项目。

迁移:

Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedInteger('projects_id')->nullable(); 
            // Add column that specifies what project this belongs to
            $table->timestamps();
            $table->string('title');
            $table->text('short_text'); // Mandetory first 150 chars of content
            $table->text('content');
            $table->char('is_featured'); // Y for N for No
            $table->string('posted_by'); // Auth user
        });

关系:

public function articles()
{
    return $this->hasMany('App\Models\Article', 'projects_id', 'id');
    // Use the projects_id we just added to get all 
    // articles for that project
}

我建议您阅读Laravel文档,特别是迁移和关系。

https://laravel.com/docs/5.8/eloquent-relationships

https://laravel.com/docs/5.8/migrations

更新2:

文章迁移:https://pastebin.com/QaDUzG9x

项目迁移:https://pastebin.com/4i9Bg5vQ

文章和项目模型:https://pastebin.com/8GWmcx7U

种子:https://pastebin.com/MDi2nW5N

商品和项目工厂:https://pastebin.com/BUFfP7iv

下载项目:http://www.mediafire.com/file/wv5188frvd0k9m0/devtest.zip/file

使用php artisan tinkerApp\Project::first()->articles,我可以在数据库中获得第一个Project及其所有文章。