Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Версия Laravel: 5.4
Версия PHP: 5.6
Задача, что должно происходить _в целом_, техническое задание:
Нужно реализовать сортировку по связанной таблице.
Есть таблица doctors(id, name, desc) и reviews_doctors(id, name, text, recommends) Связь один ко многим.
Нужно отсортировать всех врачей по популярности(количеству положительных отзывов(recommends = 1))
app\Http\Controllers\DoctorsController.php
//Пока дошел до такого:
$doctors = Doctor::with('reviews')
->join('reviews_doctors', 'doctors.id', '=', 'reviews_doctors.id_doctor')
->orderBy('reviews_doctors.recommends', 'asc')
->get();
//Но это не совсем то что мне поможет(((
app\Models\ReviewsDoctor.php
public function doctor()
{
return $this->belongsTo('App\Doctor', 'id_doctor', 'id');
}
app\Models\Doctor.php
public function reviews() {
return $this->hasMany('App\Reviews_doctor', 'id_doctor', 'id');
}
Не в сети
->join не нужно делать. вообще элоквент не любит джойны и группировки – они нарушают принцип «одна запись из базы – одна сущность в моделях», посколько могут вернуть несколько записей на одну модель, в случаях когда а) запрашивается связь один-ко-многим со стороны «один» или б) запрашивается связь многие-ко-многим. данный пример соответствует случаю (а)
вообще, данная задача решается иначе. видишь ли, на каждый чих запрашивать связанную таблицу только чтобы отсортировать записи в основной – это может быть просто и очевидно с точки зрения правильной нормализованной структуры реляционной базы, но с точки зрения эффективности и производительности – количество рекомендаций лучше «закэшировать» в поле основной таблицы и выбирать записи, не обращаясь к связанной вообще.
тут появится определённый оверхед в том плане что везде где добавляются, меняются или удаляются отзывы, нужно будет смотреть на изменения поля recommends и обновлять запись доктора, но зато выборка будет намного проще и эффективнее
ps. обрати внимание ещё на имена полей и моделей. у элоквента конечно широкие возможности настраивать это добро (которые ты и используешь в связях), но есть определённые соглашения по умолчанию, которым лучше следовать, и тогда код будет чище и читабельнее (а если кому-то потом придётся дорабатывать твой код – ещё и проще разобраться будет). во-первых, если назвать поле связи doctor_id то на связях его имя указывать будет не нужно – элоквент сам сгенерирует его из имени модели (Doctor), во-вторых, имена моделей должны следовать PSR2 (никаких подчёркиваний) и быть в единственном числе – то есть в твоём случае модель должна называться DoctorReview и элоквент по умолчанию будет искать записи в doctor_reviews – тебе не нужно будет нигде это имя явно прописывать.
Не в сети
->join не нужно делать. вообще элоквент не любит джойны и группировки – они нарушают принцип «одна запись из базы – одна сущность в моделях», посколько могут вернуть несколько записей на одну модель, в случаях когда а) запрашивается связь один-ко-многим со стороны «один» или б) запрашивается связь многие-ко-многим. данный пример соответствует случаю (а)
вообще, данная задача решается иначе. видишь ли, на каждый чих запрашивать связанную таблицу только чтобы отсортировать записи в основной – это может быть просто и очевидно с точки зрения правильной нормализованной структуры реляционной базы, но с точки зрения эффективности и производительности – количество рекомендаций лучше «закэшировать» в поле основной таблицы и выбирать записи, не обращаясь к связанной вообще.
тут появится определённый оверхед в том плане что везде где добавляются, меняются или удаляются отзывы, нужно будет смотреть на изменения поля recommends и обновлять запись доктора, но зато выборка будет намного проще и эффективнее
ps. обрати внимание ещё на имена полей и моделей. у элоквента конечно широкие возможности настраивать это добро (которые ты и используешь в связях), но есть определённые соглашения по умолчанию, которым лучше следовать, и тогда код будет чище и читабельнее (а если кому-то потом придётся дорабатывать твой код – ещё и проще разобраться будет). во-первых, если назвать поле связи doctor_id то на связях его имя указывать будет не нужно – элоквент сам сгенерирует его из имени модели (Doctor), во-вторых, имена моделей должны следовать PSR2 (никаких подчёркиваний) и быть в единственном числе – то есть в твоём случае модель должна называться DoctorReview и элоквент по умолчанию будет искать записи в doctor_reviews – тебе не нужно будет нигде это имя явно прописывать.
Рассматривал этот варианте, но думал запросом будет проще(((
За имена моделей и полей спасибо, буду теперь в курсе.
Не в сети