Laravel Eloquent - отношение отношения - три модельных отношения

Я пытаюсь преобразовать приведенный ниже запрос БД в красноречивое отношение.

$device_barcodes = ["BSC0337", "BSC0503", "BSC0626"];
$devices = DB::table('devices')
       ->leftjoin('devices_repairs', 'devices_repairs.device_id', '=', 'devices.device_id')
       ->leftJoin('staff','staff.staff_id','devices_repairs.repair_damaged_by')
       ->whereIn('barcode', $device_barcodes)
       ->get();

Пока у меня есть ниже, но я борюсь с отношениями персонала.

$devices = Devices::with('repairDetails')->whereIn('barcode', $device_barcodes)->get();

На данный момент я преодолел это с помощью приведенного ниже, но это не идеально.

foreach($devices as $device) {
           $staff_name = Staff::find($device->repairDetails->repair_damaged_by);
           $device->staff_name = $staff_name->staff_name;
 }

Я надеюсь на что-то вроде:

$devices = Devices::with('repairDetails')->with('staffDetails')->whereIn('barcode', $device_barcodes)->get();

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

Итак, основная проблема в том, что я пытаюсь связать три модели вместе.

Устройства — это топовая модель, в которой я присоединяюсь к DevicesRepairs, используя первичный и внешний ключи device_id. Но для модели Staff мне нужно присоединить devices_repairs.repair_damaged by к staff.staff_id.

Вот мои модели: Устройства:

class Devices extends Model
{
    /**
     * @var bool $timestamps Disable timestamps
     */
    public $timestamps = false;
    /**
     * @var string $table Name of the db table
     */
    protected $table = 'devices';
    /**
     * @var string $primaryKey Name of the primary key
     */
    protected $primaryKey = 'device_id';
    /**
     * @var array $fillable The attributes that are mass assignable.
     */
    protected $fillable = [
        'status',
        'order_reference',
        'model',
        'serial',
        'imei',
        'barcode',
        'mobile_number',
        'helpdesk_url_id',
        'device_notes'
    ];

    use Searchable;

    function repairDetails() {
        return $this->hasOne(DevicesRepairs::class, 'device_id');
    }

    function repairHistoryDetails() {
        return $this->hasOne(DevicesRepairsHistory::class, 'device_id');
    }

}

УстройстваРемонт:

class DevicesRepairs extends Model
{
    use HasFactory;
    protected $table = 'devices_repairs';
    protected $primaryKey = 'device_id';
    public $timestamps = false;
    protected $fillable = [
        'device_id',
        'repair_damanged_by',
        'repair_damage_type',
        'repair_date_received',
        'repair_date_sent_for',
        'repair_damage_notes',
        'repairer_name',
        'repair_is_user_damage',
        'job_number',
        'operator_date_received',
        'operator_date_received_by',
        'operator_date_sent',
        'operator_sent_by',
        'photo_id',
        'photo_id_back'
    ];

    function device() {
        return $this->hasOne(Devices::class, 'device_id');
    }

    //This doesn't work - seems to return a random staff member.
    function staffDetails() {
        return $this->hasOne(Staff::class,'staff_id','repair_damaged_by');
    }  
}

Персонал:

class Staff extends Model
{
    use searchable;

    /**
     * @var bool $timestamps Disable timestamps
     */
    public $timestamps = false;
    /**
     * @var string $table Name of the db table
     */
    protected $table = 'staff';
    /**
     * @var string $primaryKey Name of the primary key
     */
    protected $primaryKey = 'staff_id';
    /**
     * @var array $fillable The attributes that are mass assignable.
     */

    protected $fillable = [
        'staff_id',
        'staff_name',
        'manager_id',
        'is_active',
        'is_mdm_user',
        'user_id',
    ];
}

Моя конечная цель - иметь возможность возвращать такие поля, на мой взгляд:

{{$device->barcode}}
{{$device->repairDetails->repair_damage_notes}}

//The above work fine but not this:
{{$device->staffDetails->staff_name}}
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Что нового в PHP 8.1?
Что нового в PHP 8.1?
Если вы все еще используете PHP 7, то эта статья для вас. В PHP 8, а именно в PHP 8.1, встроены некоторые очень востребованные функции, которые вам...
Разработка LMS на заказ для повышения эффективности работы и обучения
Разработка LMS на заказ для повышения эффективности работы и обучения
За последние годы в образовании произошла большая революция, и сегодня почти все учебные заведения делают упор на эксклюзивное управление учебным...
1
0
15
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

рассматривать at как сводную таблицу, отношение многие ко многим между устройствами и персоналом

class Devices extends Model
{
    public function damagedBy()
    {
        return $this->belongsToMany(Staff::class, 'devices_repairs', 'device_id', 'repair_damaged_by');
    }

Таким образом, запрос будет таким

$device_barcodes = ["BSC0337", "BSC0503", "BSC0626"];
$devices = Devices::with('damagedBy')->whereIn('barcode', $device_barcodes)->get();

Огромное спасибо! Это сработало. Кажется, он возвращается в виде массива, поэтому необходимо сделать это, чтобы он отображался в моем представлении, но в остальном он отлично работает. Все еще ломаю голову над отношениями. $device->damagedBy[0]->имя_сотрудника

masterg174 10.04.2022 13:47

@ masterg174 возвращает массив, потому что это то, что предлагает ваша структура базы данных. устройство можно ремонтировать несколько раз, поэтому оно может иметь несколько «damagedBy» для каждого ремонта.

N69S 10.04.2022 13:54

Спасибо, это имеет смысл. Хотя в моем случае на самом деле у меня есть отдельная таблица истории ремонтов для хранения исторических ремонтов после завершения ремонта. Поскольку устройства уникальны, только один экземпляр конкретного устройства (PK:device_id) может одновременно храниться в таблице ремонтов. Я обнаружил, что это также работает:

masterg174 10.04.2022 14:28

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