Как создать трехсторонний пивот с помощью Eloquent ORM - PullRequest
0 голосов
/ 23 октября 2018

Очень плохо знаком с Laravel, но мне нравится то, что я вижу до сих пор.

Я работаю над приложением, в котором клиенты посещают сессии, и сессии могут посещать многие клиенты.В дополнение к этому, Клиенты могут также выполнить Оценки в Сессиях, которые они посещают на индивидуальной основе (то есть один клиент = одна оценка).Также стоит указать, что они могут или не могут завершить оценку.

Лучший способ объяснить это ...

enter image description here

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

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

Какой-то соответствующий код:

class Client extends Model
{
    public function sessions()
    {
        return $this->hasMany('App\Session');
    }

    public function assessments()
    {
        return $this->hasMany('App\Assessment');
    }
}

class Session extends Model
{
    public function clients()
    {
        return $this->hasMany('App\Client');
    }

    public function assessments()
    {
        return $this->hasMany('App\Assessment');
    }
}

//This is where I am having difficulty...

class Assessment extends Model
{
    public function client()
    {
        return $this->hasOne('App\Client');
    }

    public function session()
    {
        return $this->hasOne('App\Session');
    }
}

Проблема, с которой я сталкиваюсьэто то, как создать эти трехсторонние отношения между «Клиентом», «Сессией» и «Оценкой» таким образом, чтобы обеспечить целостность и доступность.

Несколько вещей, о которых я думал:

  1. Создайте сводную таблицу "client_session" и добавьте в нее дополнительное поле, называемое "valuation_id ", и используйте его для привязки оценки к уникальной комбинации клиента и сеанса.Я не уверен, как (или даже если это возможно) определить такое отношение к таблице без модели.

  2. Используйте «Оценки» в качестве сводной таблицы.Мне не очень нравится эта идея, так как возможно, что никакие оценки не проводятся, но мне все еще нужно, чтобы эти отношения между клиентом и сессией и сохранение их в «Оценках» были неправильными.

  3. Создатьотдельная таблица «Посещаемость» и связанный с ней «сводный класс», т. е. расширяет сводную модель, а не модель - действительно не уверен насчет этого!

Мне удалось структурировать данные с использованием простых таблиц и использовать INNERПРИСОЕДИНЯЕТСЯ от Laravel, но хотел понять, как лучше всего реализовать это с помощью Eloquent.

Я также видел отношение ownToMany () с использованием Pivot (т.е. расширяет Pivot, а не Model) или отношения hasManyThrough ().

Я также видел https://github.com/jarektkaczyk/Eloquent-triple-pivot, но это не поддерживалось в течение 4 лет, поэтому я предполагаю, что это можно сделать с любыми кораблями с Eloquent / Laravel.

Любая помощь, оченьпризнателен!

**** ОБНОВЛЕНИЕ ****

Хорошо, @barghouthi очень помогла мне с моим пониманием.В настоящее время мои модели выглядят следующим образом:

class Client extends Model
{
    public function sessions()
    {
        return $this->belongsToMany('App\Session', 'attendance')->using('App\Attendance');
    }
}

class Session extends Model
{
    public function clients()
    {
        return $this->belongsToMany('App\Client', 'attendance')->using('App\Attendance');
    }
}

class Attendance extends Pivot
{
    public function client()
    {
        return $this->belongsTo('App\Client', 'attendance');
    }

    public function session()
    {
        return $this->belongsTo('App\Session', 'attendance');
    }

    public function assessment()
    {
        return $this->hasMany('App\Assessment','attendance');
    }
}

class Assessment extends Model
{
    public function attendance()
    {
        return $this->belongsTo('App\Attendance');
    }

    public function client()
    {
        // for now
        return $this->attendance()->client();
    }

    public function session()
    {
        // for now
        return $this->attendance()->session();
    }
}

Я специально переименовал сводную таблицу, чтобы она отражала класс сводок.

Я поместил некоторые фиктивные данные в таблицу посещаемости, напримерчто:

enter image description here

Когда я запрашиваю сеансы клиента для идентификатора клиента 1, это возвращает четыре записи, а не две.Четвертое правильно с точки зрения таблицы посещаемости, но я хотел бы, чтобы возвращались только две записи - то есть сеансы.

**** ОБНОВЛЕНИЕ

Хорошо - так что я много учусь и яЯ не совсем там.Это мое текущее решение:

class Client extends Model
{
    public function sessions()
    {
        return $this->belongsToMany('App\Session', 'attendance')->using('App\Attendance')->distinct('session_id');
    }

    public function assessments()
    {
        return $this->hasManyThrough('\App\Assessment', '\App\Attendance', 'client_id', 'id');
    }
}

class Session extends Model
{
    public function clients()
    {
        return $this->belongsToMany('App\Client', 'attendance')->using('App\Attendance')->distinct('client_id');
    }

    public function assessments()
    {
        return $this->hasManyThrough('\App\Assessment', '\App\Attendance', 'session_id', 'id');
    }
}

class Assessment extends Model
{   
    public function client()
    {
        return $this->belongsToMany('\App\Client', 'attendance', 'id', 'client_id')->using('\App\Attendance');
    }

    public function session()
    {
        return $this->belongsToMany('\App\Session', 'attendance', 'id', 'session_id')->using('\App\Attendance');
    }
}

В таблице посещаемости просто есть id, client_id и session_id.Я полагал, что в оценке_ не было необходимости, поскольку существует отношение один к одному (т. Е. Оценка может выполняться или не выполняться клиентом на определенной сессии)

class Attendance extends Pivot
{
    public function clients()
    {
        return $this->belongsTo('App\Client', 'attendance');
    }

    public function sessions()
    {
        return $this->belongsTo('App\Session', 'attendance');
    }

    public function assessments()
    {
        return $this->belongsTo('App\Assessment','attendance');
    }
}

Это, по-видимому,сделать трюк врозь по большей части.Если я попытаюсь позвонить

$assessment->client->id

, я получу следующее:

Property [id] does not exist on this collection instance.

Что означает, что мои отношения в Оценке не совсем правильные, если я хочу прочитать свойства связанных элементов.

Когда я использую

$assessment->client

Выход составляет

[{"id":1,"created_at":"2018-10-24 19:15:41","updated_at":"2018-10-24 19:15:41","date_of_birth":"26 Sep 1974","gender":1,"initial_contact_date":"2013-05-01","initial_session_offered_date":"2002-07-06","contact_from":1,"presentation":"Vitae qui et nesciunt iste autem numquam earum. Illo repudiandae deleniti vel nesciunt non iure. Sunt est nemo ut excepturi illum temporibus.","counsellor_id":1,"pivot":{"id":1,"client_id":1}}]

Так что я предполагаю, что я близко.

1 Ответ

0 голосов
/ 23 октября 2018

, так что если у вас есть таблица client_session или attendance с id, client_id, session_id, и вы используете эту таблицу в качестве внешнего ключа в таблице оценок.

Дело в том, что сводная таблица может быть моделью

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

class Client extends Model
{
    public function sessions()
    {
        // using intermediate model
        return $this->belongsToMany('App\Session')->using('App\Attendance');
    }
}

class Session extends Model
{
    public function clients()
    {
        // using intermediate model
        return $this->belongsToMany('App\Session')->using('App\Attendance');
    }
}


class Attendance extends Pivot
{
    public function clients()
    {
        return $this->belongsTo('App\Client');
    }

    public function session()
    {
        return $this->belongsTo('App\Session');
    }

    public function Assessments()
    {
        return $this->hasMany('App\Assessment');
    }

}



class Assessment extends Model
{
    public function attendance()
    {
        return $this->belongsTo('App\Attendance');
    }

    public function client()
    {
        // for now
        return $this->attendance()->client();
    }

    public function session()
    {
        // for now
        return $this->attendance()->client();
    }
}

, таким образомВы не можете пройти оценку без участия, а посещаемость может иметь много оценок.

Оценка будет выглядеть так:

id, attendance_id: относится к клиенту и сеансам

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