Есть 4 таблицы:
factories
factory_contacts
factory_notifications
users
Мы, как пользователь заходим на страницу и видим список заводов. Открывая завод мы видим список контактов, открвая контакт мы видим с ним переписку. В зависимости от того с какого пользователя зашли, разная переписка соответсвенно.
Так вот, переписка работает таким образом, что тупо отлавливает входящие сообщения из почты. И каждый раз когда приходит новое сообщение, в таблице factory_notifications в колонку new_mail плюсуется 1 (всего там три колонки - factory_contact_id и user_id, ну ил new_mail);
Проблема в том, что мне нужно отсорировать вывод factories по последнему сообщению. То есть для каждого пользователя сортировка будет разная.
Как все сделать одним запросом и возможно ли это вообще?
Остановился на вот таком извращении, которое все равно не сортирует правильно:
$factories = Factory::orderBy($sortBy, $orderBy)->with('contacts')->with('discounts')->with('markups')->with('pickupAddresses')->with('legalAddress')->with('realAddress')->with('postAddress')->paginate($request->perPage);
foreach ($factories as $factory) {
$lastMessage = 0;
foreach ($factory->contacts as $contacts) {
foreach ($contacts->notifications as $notification) {
if ($lastMessage < strtotime($notification->updated_at)) {
$lastMessage = strtotime($notification->updated_at);
}
}
}
$factory->last_message_time = date('d-m-Y H:i:s', $lastMessage);
}
if ($sortBy == 'updated_at') {
if ($orderBy == 'ASC') {
$factories->sortBy('last_message_time');
} else {
$factories->sortByDesc('last_message_time');
}
}
UPD: Удалось получить нужный вариант, но с дубликатами. Distinct не получается впихнуть... Может есть какие предложения?
Paginator::currentPageResolver(function () use ($currentPage) {
return $currentPage;
});
$factories = Factory::select(DB::raw("factories.*, factory_contacts.*, factory_notifications.updated_at AS last_message_time"))
->leftJoin('factory_contacts', 'factories.id', '=', 'factory_contacts.factory_id')
->leftjoin('factory_notifications', function ($join) use ($request) {
$join->on('factory_notifications.id', '=', DB::raw("(SELECT id FROM factory_notifications WHERE factory_notifications.factory_contact_id = factory_contacts.id AND factory_notifications.user_id = 6 ORDER BY factory_notifications.updated_at DESC)"));
})->orderByRaw('factory_notifications.updated_at DESC NULLS LAST')
->with('contacts')->with('discounts')->with('markups')->with('pickupAddresses')->with('legalAddress')->with('realAddress')->with('postAddress')->paginate($request->perPage);
return response()->json($factories, 200);
UPD2: Решил вот так, но ох как не нравится мне это решение:
$orderBy = $request->descending ? 'DESC NULLS LAST' : 'ASC NULLS LAST';
$sortBy = $request->sortBy ? $request->sortBy : 'factory_notifications.updated_at';
$currentPage = $request->page;
Paginator::currentPageResolver(function () use ($currentPage) {
return $currentPage;
});
// Don't touch!! Or check app\Providers\AppServiceProvider.php before making changes!
$factories = Factory::select(DB::raw("factories.*, factory_contacts.factory_id, factory_notifications.updated_at AS last_message_time"))
->leftJoin('factory_contacts', 'factories.id', '=', 'factory_contacts.factory_id')
->leftjoin('factory_notifications', function ($join) use ($request) {
$join->on('factory_notifications.id', '=', DB::raw("(SELECT id FROM factory_notifications WHERE factory_notifications.factory_contact_id = factory_contacts.id AND factory_notifications.user_id = $request->user_id ORDER BY factory_notifications.updated_at DESC)"));
})->orderByRaw($sortBy.' '.$orderBy)
->with('contacts')->with('discounts')->with('markups')->with('pickupAddresses')->with('legalAddress')->with('realAddress')->with('postAddress')->get();
$factories = $factories->unique('factory_id')->paginate($request->perPage);
return response()->json($factories, 200);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть строкаМне нужно по регулярному выражению обернуть все совпадения в тег span
Нужно выбрать 4 дня недели, включая сегодняшнийЖелательно использовать инструменты, входящие в Laravel, так как проект создан с помощью этого...