Laravel Eloquent - присоединиться к 2 таблицам через другую таблицу

Я строю отношения между двумя таблицами через третью таблицу. Всего у меня 3 таблицы.

1.) адреса

Schema::create('addresses', function (Blueprint $table) {
    $table->increments('id');
    $table->text('line_1_number_building')->nullable();
    $table->text('line
Schema::create('staffs', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('staff_category_id');
    $table->integer('gender_id');
    $table->text('staff_job_title')->nullable();
    $table->text('staff_first_name')->nullable();
    $table->text('staff_middle_name')->nullable();
    $table->text('staff_last_name')->nullable();
    $table->text('staff_qualifications')->nullable();
    $table->date('staff_birth_date');
    $table->longText('other_staff_details')->nullable();
    $table->timestamps();
});
number_street')->nullable(); $table->text('line
Schema::create('staff_addresses', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('staff_id');
    $table->integer('address_id');
    $table->date('date_address_from')->nullable();
    $table->date('date_address_to')->nullable();
    $table->timestamps();
});
area_locality')->nullable(); $table->text('city')->nullable(); $table->text('zip_code')->nullable(); $table->text('state_province_county')->nullable(); $table->text('country')->nullable(); $table->longText('other_address_details')->nullable(); $table->timestamps(); });

2.) персонал

Schema::create('staffs', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('staff_category_id');
    $table->integer('gender_id');
    $table->text('staff_job_title')->nullable();
    $table->text('staff_first_name')->nullable();
    $table->text('staff_middle_name')->nullable();
    $table->text('staff_last_name')->nullable();
    $table->text('staff_qualifications')->nullable();
    $table->date('staff_birth_date');
    $table->longText('other_staff_details')->nullable();
    $table->timestamps();
});

3.) staff_addresses

Schema::create('staff_addresses', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('staff_id');
    $table->integer('address_id');
    $table->date('date_address_from')->nullable();
    $table->date('date_address_to')->nullable();
    $table->timestamps();
});

Теперь я хочу получить список всех адресов для любой записи персонала. Я попробовал код ниже, но он возвращает адреса, соответствующие идентификатору идентификатора персонала.

Что я пробовал

public function saddresses()
{
    return $this->hasManyThrough('App\addresses','App\staff_addresses','staff_id','id');
}

Что я получил

Address : [{"id":3,"line_1_number_building":"Hasan 2 line 1","line_2_number_street":"Hasan 2 line 2","line_3_area_locality":"Hasan 2 line 3","city":"Hasan 2 city","zip_code":"Hasan 2 zip code","state_province_county":"Hasan 2 state","country":"Hasan 2 country","other_address_details":"Hasan 2 other details","created_at":null,"updated_at":null,"staff_id":5},{"id":4,"line_1_number_building":"Sadiq 2 line 1","line_2_number_street":"Sadiq 2 line 2","line_3_area_locality":"Sadiq 2 line 3","city":"Sadiq 2 city","zip_code":"Sadiq 2 zip code","state_province_county":"Sadiq 2 state","country":"Sadiq 2 country","other_address_details":"Sadiq 2 other details","created_at":null,"updated_at":null,"staff_id":5}] 

Лучший вид

Подскажите пожалуйста, как построить нормальные отношения?

С уважением, Хасан Раджани.


person Hasan Rajani    schedule 07.11.2018    source источник
comment
показать вам функцию контроллера, которая красноречиво   -  person Emtiaz Zahid    schedule 07.11.2018
comment
Из ваших таблиц кажется, что вы можете захотеть установить отношение ownToMany.   -  person adam    schedule 07.11.2018


Ответы (2)


Это решение идеально @Capt. Тимо. Но если вам нужен адрес для конкретного сотрудника, то здесь я предоставил решение.

Вы должны определить эту функцию в Модели персонала.

public function addresses() { return $this->belongsToMany('App\addresses'); }

Запрос для получения всех адресов $staffId (где $staffId — это идентификатор таблицы персонала)

$data = Staff::with('addresses')->where('id', $staffId)->first();

А также, если вы хотите получить дополнительные атрибуты в сводной таблице, вы должны указать их при определении отношения.

public function addresses() { return $this->belongsToMany('App\addresses')->withPivot('date_address_from', 'date_address_to'); }

Кроме того, вы можете автоматически поддерживать столбцы created_at и updated_at, используя метод withTimestamps в отношении.

Для справки: https://laravel.com/docs/5.7/eloquent-relationships#many-to-many

person Vandit P. Kotadiya    schedule 07.11.2018
comment
Спасибо Вандит П. Котадия за вашу помощь и руководство :), Однако я нашел еще одно быстрое решение моей проблемы на этом сайте (laraveldaily.com/pivot-tables-and-many-to-many-relationships) создал новую функцию "адреса" в модели персонала, а затем добавил имя сводной таблицы и объединение имен полей в качестве аргументов ===› (возврат $this-›belongsToMany('App\addresses','staff_addresses','staff_id','address_id');) - person Hasan Rajani; 08.11.2018

Во-первых, попробуйте исправить свои соглашения об именах. Все было бы намного проще, если бы вы следовали соглашению об именах laravel. Вот руководство.

  • Сводные таблицы должны содержать названия моделей в единственном числе в алфавитном порядке (изменить staff_addresses на address_staff).

Затем используйте отношение belongsToMany.

Модель сотрудника:

public function addresses()
{
    return $this->belongsToMany('App\addresses');
}

Вот как вы запрашиваете:

$data = Staff::with('addresses')->get();
person Kapitan Teemo    schedule 07.11.2018
comment
Спасибо капитану Тимо за руководство по соглашению об именах, это мне очень поможет :). На самом деле я изучаю laravel и не уверен во многих функциях и правилах. - person Hasan Rajani; 08.11.2018
comment
Для моей проблемы это решение оказалось полезным (laraveldaily.com/ сводные таблицы-и-многие-ко-многим-отношениям) создал новую функцию «адреса» в модели персонала, а затем добавил имя сводной таблицы и имя поля соединения в качестве аргументов ===› (возврат $this-› принадлежитToMany('Приложение\адреса','адреса_персонала','id_персонала','id_адреса');) - person Hasan Rajani; 08.11.2018
comment
Если вы следуете соглашениям об именах laravel, вам не нужно указывать имя таблицы в вашем отношении, которое равно staff_addresses. Laravel автоматически ищет address_staff как опорную, так как вы присоединяетесь к таблицам addresses и staffs. Ваш аргумент будет просто return $this->belongsToMany('App\addresses'); - person Kapitan Teemo; 08.11.2018
comment
Да, я понимаю. Я попытался изменить соглашения об именах и выполнить повторную миграцию, но это испортило всю мою настройку, поэтому я подумал, что на данном этапе делать этот шаг не очень хорошая идея. Однако это поможет мне в следующем проекте :). В настоящее время изучаю laravel :), и я не хочу терять интерес, переделывая все заново. Спасибо за вашу помощь - person Hasan Rajani; 09.11.2018