Я не уверен, как это называется, поэтому я объясню это как можно лучше.
У меня есть тикет-система, где я вывожу все комментарии в один раздел. В другом разделе я отображаю соответствующую информацию, такую как «Сторонник изменен», «Название заявки изменено», «Статус заявки изменен» и так далее.
Текущий отображаемый (без стилей) HTML: https://jsfiddle.net/2afzxhd8/
Я хотел бы объединить эти два раздела в один, чтобы эта связанная информация отображалась между комментариями тикета. Все (комментарии + связанная информация) должно отображаться отсортированным по временной метке created_at.
Отображена новая цель (без стилей) HTML: https://jsfiddle.net/4osL9k0n/
Билетная система в моем случае имеет следующие красноречивые модели (и таблицы):
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tickets extends Model
{
use SoftDeletes;
protected $fillable = [
'tracking_number', 'customer_id', 'category_id',
'priority_id', 'subject', 'status_id', 'is_done',
'supporter_id'
];
protected $hidden = [
];
protected $dates = ['deleted_at'];
public function status() {
return $this->belongsTo(TicketStatuses::class, 'status_id');
}
public function priority() {
return $this->belongsTo(TicketPriorities::class, 'priority_id');
}
public function category() {
return $this->belongsTo(TicketCategories::class, 'category_id');
}
public function supporter() {
return $this->belongsTo(User::class, 'supporter_id');
}
public function operations() {
return $this->hasMany(TicketOperations::class, 'ticket_id');
}
public function comments() {
return $this->hasMany(TicketComments::class, 'ticket_id');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class TicketComments extends Model
{
use SoftDeletes;
protected $fillable = [
'ticket_id', 'text', 'user_id', 'is_html',
'email_reply', 'internal_only'
];
protected $hidden = [
];
protected $dates = ['deleted_at'];
public function ticket() {
return $this->belongsTo(Tickets::class, 'id', 'ticket_id');
}
public function user() {
return $this->belongsTo(User::class, 'user_id');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class TicketOperations extends Model
{
use SoftDeletes;
protected $fillable = [
'ticket_id', 'user_id', 'ticket_activity_id',
'old_value', 'new_value'
];
protected $hidden = [
];
protected $dates = ['deleted_at'];
public function ticket() {
return $this->belongsTo(Tickets::class, 'ticket_id');
}
public function activity() {
return $this->belongsTo(TicketActivities::class, 'ticket_activity_id');
}
public function user() {
return $this->belongsTo(User::class, 'user_id');
}
}
Пожалуйста, не беспокойтесь о CSS - в моем случае он стилизован. Просто здесь это не актуально.
Любая идея, как мне нужно обновить свое представление, чтобы иметь возможность создавать целевой HTML?






Насколько я понимаю, у вас есть данные, полученные из нескольких моделей.
Итак, что вы можете сделать, это объединить информацию в новый массив:
Например, представьте, что данные об истории заявок хранятся в массиве с именем:
$arrTicketHistory;
И учтите, что информация об обновлениях заявок хранится в массиве с именем:
$arrTicketUpdates;
Объедините эти два массива и присвойте результат другому массиву, скажем:
$arrDatesAndIDs;
Теперь попробуйте отсортировать массив $arrDatesAndIDs на основе метки времени, т. е. created_at. Затем отобразите результат с помощью простого цикла for.
Вы можете добавить пользовательский параметр в массивы $arrTicketUpdates и $arrDatesAndIDs просто для уникальности. Это может помочь вам определить, какой тип информации относится к билету.
Вы можете использовать функцию массива array_msort(), функцию php, для сортировки многомерного массива.
Я только что нашел этот отвечать, но у него есть одна большая проблема: в худшем случае он перезаписывает некоторые объекты другими объектами, и это приводит к возможным отсутствующим объектам в коллекции.
Из Документация Laravel: Коллекции:
The
mergemethod merges the given array or collection with the original collection. If a string key in the given items matches a string key in the original collection, the given items's value will overwrite the value in the original collection.
Из-за этого мне пришлось обновить логику до этого:
$ticket = Tickets::where('tracking_number', '=', $request->tracking_number)->first();
$comments = $ticket->comments;
$operations = $ticket->operations;
$history_unsorted = new Collection();
$history_unsorted = $history_unsorted->merge($comments);
$history_unsorted = $history_unsorted->merge($operations);
$history = $history_unsorted->sortBy('created_at');
Это позволяет избежать перезаписи оригинальной коллекции.
При этом я могу просто перебрать $history:
@foreach($history as $history_item)
@if ($history_item instanceof App\TicketOperations)
<!-- Ticket Operation -->
@else
<!-- Ticket Comment (Text) -->
@endif
@endforeach
Я пробовал это раньше, так как это было бы гораздо более простым решением, но проблема в том, что в худшем случае он перезаписывает некоторые объекты, а затем вы пропускаете некоторые объекты из коллекций. Вот почему я обновил этот комментарий немного другим решением. :) Я обновлю свой комментарий в ближайшие минуты с кратким объяснением.
Разве не должно работать следующее?
$history = $ticket->comments->merge($ticket->operations)->sortBy('created_at');