Laravel Eloquent - цикл For внутри сидера ведет себя странным образом - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть две модели, статья и проект.У проекта может быть много связанных статей, и статья может принадлежать одному проекту или нет.У меня есть два сеялки projectseeder и articleseeder.Сеялка статей сначала вызывается и работает нормально, а затем я пытаюсь запустить цикл внутри сеялки проекта, чтобы связать несколько случайных статей, в результате в коллекцию добавляется только одна статья.Странно, но добавляемая статья имеет тот же идентификатор, что и проект, т. Е. Если идентификатор проекта равен 1, то связанный идентификатор статьи также равен 1. Я не в курсе, почему цикл for внутри податчика проекта не работает должным образом.

   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. Я хотел бы выбрать случайные статьи вместо всех проектов с одинаковыми статьями.

ОБНОВЛЕНИЕ # 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)]),
    ];
});

Теперь у статей либо нулевые, либо случайные идентификаторы проекта, поскольку идентификатор проекта и статьи теперь автоматически связаны спроекты.Тем не менее, большое спасибо за ваше драгоценное время.Хорошего дня.

1 Ответ

0 голосов
/ 17 апреля 2019

Первый раз отправляю ответ.:)

Ваше отношение к статьям () использует столбец идентификатора из обеих таблиц для получения статей.Это приведет к тому, что вы получите только одну статью.Если вы добавите столбец projects_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 tinker и App\Project::first()->articles, я смог получить первый Проект в базе данных вместе со всеми его статьями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...