Отношения Laravel многие ко многим с несколькими настраиваемыми сводными таблицами?

Надеюсь, я не задаю уже ответ на вопрос, но, используя все поисковые запросы, которые я могу придумать, я не могу найти решение этой проблемы:

У меня есть две таблицы, companies и respondents

Иногда респондент может Выбрать одной или нескольким компаниям. Компания может быть выбранный одним или несколькими респондентами.

В других случаях респондент может ставка одной или нескольким компаниям. Компания может быть оцененный одним или несколькими респондентами.

Ответчик может как Выбрать, так и ставка компании. (Действительно, все компании, которые оценивает респондент, они должны были выбрать, но они не оценивают все компании, которые выбирают).

Еще одна сложность заключается в том, что респондентом является наемный рабочий только одной компании, а также назначен одной или более компаний для выбора и оценки.

Я считаю, что нужно иметь несколько настраиваемых точек поворота:

//relationship between 'companies' and 'respondents' to show who they selected 
selected_companies 

//relationship between 'companies' and 'respondents' to show who they rated 
rated_companies 

//relationship between 'companies' and 'respondents' to show which companies a respondent was nominated by 
nominating_companies

//relationship between 'companies' and 'respondents' to show who a respondent is employed by
employment

Я предполагаю, что последний вариант прост для многих, поэтому я могу просто поместить пользовательский с именем FK для employer_id в таблицу respondents.

Помимо этого, я очень застрял в том, как это реализовать. Я знаю, что настраиваемые промежуточные модели поворота - это вещь, но я также не могу понять, как это реализовать.

Возможно, это не решит вашу проблему напрямую, но изучите Custom Ploymorphic Many to Many Relationships laravel.com/docs/5.7/…, по крайней мере, используя это, вам не нужно определять несколько промежуточных сводных таблиц.

karmendra 10.12.2018 12:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
4
1
2 378
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, вот как я с этим справился.

Пользовательская сводная таблица

В сводной таблице я добавил столбец type. Вот как теперь выглядит моя миграция сводной таблицы company_respondent:

    Schema::create('company_respondent', function (Blueprint $table) {
        $table->unsignedInteger('company_id');
        $table->unsignedInteger('respondent_id');
        $table->string('type');

        $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
        $table->foreign('respondent_id')->references('id')->on('respondents')->onDelete('cascade');
        $table->primary(['company_id','respondent_id','type']);
    });

Обратите внимание, что в качестве первичного ключа я использую все три столбца. Это позволит мне заявить о разных типах отношений между одной и той же парой компания-респондент, например когда респондент выбрал компанию, я могу сохранить selected, а когда они оценили компанию, я могу сохранить rated в столбце type.

withPivot

Прежде чем я смогу это сделать, мне нужно сказать Laravel, что этот новый столбец в моделях Company и Respondent следует ожидать, используя withPivot() при определении взаимосвязи. Мне нужно сделать это с обеих сторон отношений:

//Respondent.php

    use App\Company;

    public function companies() 
    {
        return $this->belongsToMany(Company::class)->withPivot('type');
    }


//Company.php

    use App\Respondent;

    public function respondents() 
    {
        return $this->belongsToMany(Respondent::class)->withPivot('type');
    }

После этого я могу сохранить данные в этом столбце при сохранении отношения и использовать его для фильтрации.

Хранение:

$respondent->companies()->attach($companies_selected, ['type'=> 'selected']);

Где $companies_selected - это либо одиночный идентификатор, либо массив идентификаторов.

Фильтрация:

//returns an array of company names that a respondent with an id of `2` has selected.

$company_names = Respondent::find(2)
                    ->companies()
                    ->wherePivot('type','selected')
                    ->pluck('name')->toArray();

Я могу просто заменить selected, rated, nominated или что-нибудь еще, что мне нравится, для определения различных типов отношений, которые могут существовать между двумя таблицами.

Я надеюсь, что это поможет кому-то другому, или я получу отзывы о том, как это сделать лучше.

Другие вопросы по теме