Очень новичок в Laravel, но мне нравится то, что я вижу до сих пор.
Я работаю над приложением, в котором клиенты посещают сеансы, а сеансы могут посещаться многими клиентами. В дополнение к этому, клиенты могут также выполнять оценки на сессиях, которые они посещают, на индивидуальной основе (т.е. один клиент = одна оценка). Также стоит отметить, что они могут или не могут сдавать экзамен.
Лучший способ объяснить это ...
Также важно отметить, что данные должны быть согласованными - завершенная оценка должна выполняться в сеансе, в котором присутствовал клиент. то есть клиент должен присутствовать на сеансе - то же самое верно и в обратном случае - клиент не может завершить и оценить сеанс, на котором он или она не присутствовал.
Это скорее попытка обдумать лучшую структуру для этого и использовать 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');
}
}
Проблема, с которой я сталкиваюсь, заключается в том, как создать эти трехсторонние отношения между «клиентом», «сеансом» и «оценкой» таким образом, чтобы обеспечить соблюдение целостности и доступность.
Я думал о нескольких вещах:
Создайте сводную таблицу client_session, добавьте в нее дополнительное поле под названием Assessment_id и используйте его для привязки оценки к уникальной комбинации клиента и сеанса. Я не уверен, как (или даже если это возможно) определить такое отношение к таблице без модели.
Используйте «Оценки» в качестве сводной таблицы. Мне не очень нравится эта идея, поскольку возможно, что оценки не проводятся, но мне все еще нужны эти отношения между клиентом и сеансом, и хранить это в «Оценках» кажется неправильным.
Создайте отдельную таблицу «Посещаемость» и связанный с ней «сводный класс», т.е. расширяет сводную, а не модель - действительно не уверен в этом!
Мне удалось структурировать данные с помощью простых таблиц и использовать ВНУТРЕННИЕ СОЕДИНЕНИЯ вне 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();
}
}
Я намеренно переименовал сводную таблицу, чтобы она отражала класс Pivot.
Я поместил фиктивные данные в таблицу посещаемости, например:
Когда я запрашиваю клиентские сеансы для идентификатора клиента 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. Я решил, что нет необходимости в Assessment_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}}]
Так что, думаю, я близок.






поэтому, если у вас есть таблица 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: относится к клиенту и сеансам
Это не проблема, оценка относится к посещаемости, но по посещаемости может быть несколько оценок. на самом деле в моем ответе есть ошибка. Оценка - это нормальная модель (расширяет Модель) Сейчас исправлю
Я заметил проблему с опорой, которая означает, что часть этого происходит! Что касается проблемы в моем последнем комментарии, это потому, что связь возвращает данные из таблицы «посещаемости», а не из конечной таблицы «оценки». Данные верны, но мне это нужно, чтобы вытащить DISTINCT записи (а-ля SQL), чтобы они просто давали мне сеансы - в отличие от записи для каждой уникальной комбинации.
если вы приведете несколько примеров, будет легче понять !.
Зачем вам иметь два экземпляра посещаемости для одного и того же клиента и сеанса?
Потому что клиент может пройти более одного экзамена за сеанс.
так что у вас будет таблица оценок, например> id, attendance_id, assessment_details. вы просто добавите сюда еще одну запись с тем же посещаемостью_id, таким образом у вас будет две оценки одним и тем же клиентом за один сеанс,
Это определенно поставило меня на верный путь. Спасибо. Одна (надеюсь, последняя!) Вещь, с которой я борюсь, - это то, что клиент может выполнить две оценки за один сеанс. Проблема здесь в том, что когда дело доходит до извлечения сеансов, он предоставляет две записи, то есть
Record #1: client_id:1 session_id:1 assessment_id:1 Record #2: client_id:1 session_id:1 assessment_id:2. Данные являются надежными. Мне просто нужен способ отфильтровать это, чтобы он извлекал только отдельные сеансы, а не каждую запись «посещаемости».