У меня две коллекции, и я хочу объединить ее с одной переменной (конечно, с упорядочением на один столбец – created_at
). Как я могу это сделать?
Мои контроллеры выглядят так:
$replies = Ticket::with('replies', 'replies.user')->find($id); $logs = DB::table('logs_ticket') ->join('users', 'users.id', '=', 'mod_id') ->where('ticket_id', '=', $id) ->select('users.username', 'logs_ticket.created_at', 'action') ->get();
Мой вывод выглядит, например:
Ответы:
ID | ticket_id | username | message | created_at 1 | 1 | somebody | asdfghj | 2014-04-12 12:12:12 2 | 1 | somebody | qwertyi | 2014-04-14 12:11:10
Журналы:
ID | ticket_id | username | action | created_at 1 | 1 | somebody | close | 2014-04-13 12:12:14 2 | 1 | somebody | open | 2014-04-14 14:15:10
И я хочу что-то вроде этого:
ticket_id | table | username | message | created_at 1 |replies| somebody | asdfghj | 2014-04-12 12:12:12 1 | logs | somebody | close | 2014-04-13 12:12:14 1 | logs | somebody | open | 2014-04-14 11:15:10 1 |replies| somebody | qwertyi | 2014-04-14 12:11:10
РЕДАКТИРОВАТЬ:
Моя модель билетов выглядит так:
<?php class Ticket extends Eloquent { protected $table = 'tickets'; public function replies() { return $this->hasMany('TicketReply')->orderBy('ticketreplies.created_at', 'desc'); } public function user() { return $this->belongsTo('User'); } } ?>
Вы не сможете получить то, что хотите.
В общем, слияние должно быть простым с помощью $collection->merge($otherCollection);
, и сортировка с помощью $collection->sort();
, Однако слияние не будет работать так, как вы хотите, из-за отсутствия уникальных идентификаторов и столбца «Таблица», который вы хотите, вам придется совершать это вручную.
Кроме того, они на самом деле собираются быть сборниками разных типов, я думаю (один из них, основанный на Eloquent\Model
будет Eloquent\Collection
, а другой – стандартной Collection
), что может привести к его собственным проблемам. Таким образом, я бы предложил использовать DB :: table () для обоих и увеличить результаты с помощью столбцов, которыми вы можете управлять.
Что касается кода для достижения этого, я не уверен, так как я не делаю много работы низкого уровня в Laravel, поэтому не знаю, как лучше всего создавать запросы. В любом случае, только потому, что это похоже на то, что вы начинаете испытывать боль, чтобы справиться с этим двумя запросами и слиянием PHP, я бы предложил сделать все это в одном запросе БД. Он будет выглядеть более аккуратным и, возможно, более удобным для обслуживания:
SQL, в котором вы нуждаетесь, выглядит примерно так:
SELECT * FROM ( SELECT `r`.`ticket_id`, 'replies' AS `table`, `u`.`username`, `r`.`message`, `r`.`created_at` FROM `replies` AS `r` LEFT JOIN `users` AS `u` ON `r`.`user_id` = `u`.`id` WHERE `r`.`ticket_id` = ? ) UNION ( SELECT `l`.`ticket_id`, 'logs' AS `table`, `u`.`username`, `l`.`action` AS `message`, `l`.`created_at` FROM `logs` AS `l` LEFT JOIN `users` AS `u` ON `l`.`user_id` = `u`.`id` WHERE `l`.ticket_id` = ? ) ORDER BY `created_at` DESC
Это довольно понятно: выполните два запроса, возвратив те же столбцы, UNION
а затем отсортируйте этот набор результатов в MySQL. Надеюсь, он (или что-то подобное, как я должен был угадать вашу структуру базы данных) будет работать для вас.
Что касается перевода этого запроса в Laravel DB::
-style, я думаю, это зависит от вас.
Немного обходной проблемы для вашей проблемы.
$posts = collect(Post::onlyTrashed()->get()); $comments = collect(Comment::onlyTrashed()->get()); $trash = $posts->merge($comments)->sortByDesc('deleted_at');
Таким образом, вы можете просто объединить их, даже если есть дубликаты идентификаторов.