Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 16.05.2017 17:57:11

Как сформировать запрос для сортировки по связанной таблице?

Версия 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');
    }

Не в сети

#2 17.05.2017 10:05:10

Re: Как сформировать запрос для сортировки по связанной таблице?

->join не нужно делать. вообще элоквент не любит джойны и группировки – они нарушают принцип «одна запись из базы – одна сущность в моделях», посколько могут вернуть несколько записей на одну модель, в случаях когда а) запрашивается связь один-ко-многим со стороны «один» или б) запрашивается связь многие-ко-многим. данный пример соответствует случаю (а)

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

тут появится определённый оверхед в том плане что везде где добавляются, меняются или удаляются отзывы, нужно будет смотреть на изменения поля recommends и обновлять запись доктора, но зато выборка будет намного проще и эффективнее

ps. обрати внимание ещё на имена полей и моделей. у элоквента конечно широкие возможности настраивать это добро (которые ты и используешь в связях), но есть определённые соглашения по умолчанию, которым лучше следовать, и тогда код будет чище и читабельнее (а если кому-то потом придётся дорабатывать твой код – ещё и проще разобраться будет). во-первых, если назвать поле связи doctor_id то на связях его имя указывать будет не нужно – элоквент сам сгенерирует его из имени модели (Doctor), во-вторых, имена моделей должны следовать PSR2 (никаких подчёркиваний) и быть в единственном числе – то есть в твоём случае модель должна называться DoctorReview и элоквент по умолчанию будет искать записи в doctor_reviews – тебе не нужно будет нигде это имя явно прописывать.

Не в сети

#3 17.05.2017 20:43:25

Re: Как сформировать запрос для сортировки по связанной таблице?

constb пишет:

->join не нужно делать. вообще элоквент не любит джойны и группировки – они нарушают принцип «одна запись из базы – одна сущность в моделях», посколько могут вернуть несколько записей на одну модель, в случаях когда а) запрашивается связь один-ко-многим со стороны «один» или б) запрашивается связь многие-ко-многим. данный пример соответствует случаю (а)

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

тут появится определённый оверхед в том плане что везде где добавляются, меняются или удаляются отзывы, нужно будет смотреть на изменения поля recommends и обновлять запись доктора, но зато выборка будет намного проще и эффективнее

ps. обрати внимание ещё на имена полей и моделей. у элоквента конечно широкие возможности настраивать это добро (которые ты и используешь в связях), но есть определённые соглашения по умолчанию, которым лучше следовать, и тогда код будет чище и читабельнее (а если кому-то потом придётся дорабатывать твой код – ещё и проще разобраться будет). во-первых, если назвать поле связи doctor_id то на связях его имя указывать будет не нужно – элоквент сам сгенерирует его из имени модели (Doctor), во-вторых, имена моделей должны следовать PSR2 (никаких подчёркиваний) и быть в единственном числе – то есть в твоём случае модель должна называться DoctorReview и элоквент по умолчанию будет искать записи в doctor_reviews – тебе не нужно будет нигде это имя явно прописывать.

Рассматривал этот варианте, но думал запросом будет проще(((
За имена моделей и полей спасибо, буду теперь в курсе.

Не в сети

Подвал раздела