Надеюсь, я не задаю уже ответ на вопрос, но, используя все поисковые запросы, которые я могу придумать, я не могу найти решение этой проблемы:
У меня есть две таблицы, 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.
Помимо этого, я очень застрял в том, как это реализовать. Я знаю, что настраиваемые промежуточные модели поворота - это вещь, но я также не могу понять, как это реализовать.






Хорошо, вот как я с этим справился.
В сводной таблице я добавил столбец 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.
Прежде чем я смогу это сделать, мне нужно сказать 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 или что-нибудь еще, что мне нравится, для определения различных типов отношений, которые могут существовать между двумя таблицами.
Я надеюсь, что это поможет кому-то другому, или я получу отзывы о том, как это сделать лучше.
Возможно, это не решит вашу проблему напрямую, но изучите Custom Ploymorphic Many to Many Relationships laravel.com/docs/5.7/…, по крайней мере, используя это, вам не нужно определять несколько промежуточных сводных таблиц.