Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

t0berius's avatar

need help with ticket system

I've stumbled about some big problem. My database design:

ticket_events: http://puu.sh/nOPi0/531fc66f94.png

ticket_replies: http://puu.sh/nOPfe/b02b7800df.png

I would like to display them in a flow like:

-ticket event
-ticket_replie
-ticket event
-ticket_replie

How to get the connection between them done? The creation_date is the same by many of them. Not all ticket_replies need a ticket_event.

0 likes
80 replies
Snapey's avatar

do I understand that you want to list these in chronological order ?

t0berius's avatar

@Snapey

it's not that simple. I would like to return an array to my view containing the items in the correct order. For this I created this code:

function orderReplies()
    {
        $ticket_replies = $this->ticket_replies->sortBy('created_at');
        $ticket_events = $this->ticket_events->sortBy('created_at');

        for ($i = 0; $i < count($ticket_replies); ++$i) 
        {
            //first entry of ticket
            if ($i == 0) 
            {

                $ticketReplie[] = $ticket_events[0];
                $ticketReplie[] = $ticket_replies[$i];
                
            }

            else
            {
                //here I need to get the events in the period (created_at) between 
            //last ticket replie and current ticket replie

            $ticketReplie[] = $ticket_replies[$i];
            }
        }

        dd($ticketReplie);

        return $ticketReplies;
    }

Any idea how I can solve my commented problem?

t0berius's avatar

@jlrdw I understand how to use Eloquent, I'm working here with collections. I'm aware there's no direct connection. Please take a look to my code I posted above.

t0berius's avatar

@khaledSMQ

my class is implemented, I just need help with the problem I commented in code.

jlrdw's avatar

I'm referring to how many tickets are in your collection, if a few eloquent is fine if 10000 you will need a custom query, you don't want 10,000 results in an array at one time. Read through that post.

jlrdw's avatar

Eloquent is not the best thing for nested foreach has to draw too many results in an array, a custom join will always be better and faster at this.

jlrdw's avatar

I can't read the png files. Nothing comes up. Sorry if I misunderstand question.

Snapey's avatar

for others. the question is how to merge two collections of different models so that they are in some sort of date order.

t0berius's avatar

@Snapey

correct, yes.

@khaledSMQ

ticket->has->ticket_replies ticket_event->has->ticket

There's no connection between ticket_events and ticket_replies.

jekinney's avatar

So many arrays in OOP!?!?!?!

Set up a relationship on the ticket_id as your images show both tables have ticket_id, and assuming the replies has the events ticket_id:

class TicketEvent extends Model
{
    public function replies()
    {
        return $this->hasMany(TicketRepy::class, 'ticket_id', 'ticket_id'); // override defaults
    }
}
foreach(TicketEvent::with('replies')->get() as $event)
{
    $event->text;
    foreach($event->replies as $reply)
    {
        $reply->text;
    }
}
t0berius's avatar

@jekinney

How to use your code in my controller? I've used this before, but now I need to include the ticket_event as well in my view.

controller: $ticket = Auth::user()->tickets()->where('tickets.id', $id)->with(['ticket_replie.file', 'ticket_replie.user', 'supporter', 'department'])->firstOrFail();

Snapey's avatar

Assuming you have a collection of $ticket_events and another of $ticket_replie

        $events_replies = $ticket_events->merge($ticket_replie);

So now you have a combined collection, and then in the view

        foreach($events_replies->sortBy('created_at') as $record){

            if(is_a($record,'App\Ticket_event')){
                 // format record as if it is an event
            } else {
                 //format record as if it a replie
            }
        
        }

jlrdw's avatar

@Snapey that gets back to my original reply, if only say one hundred in collection no big deal. But what if there were 10,000 or more in the collection, pagination has to come into play somewhere. How would you paginate the above?

Snapey's avatar

As far as I can tell, these are all events and replies in relation to one ticket so unlikely to be too much of an issue, but this is one of the things you have to consider when designing an application. Developers often design with 4 or 5 records and then the UX fails when in real-life there are more like 100 or 1000x records.

Its a question of knowing what you are dealing with.

t0berius's avatar

@Snapey

using your code triggers some problems. Let me explain a bit first. Not each ticket_replie is related to a ticket_event (they aren't related by an ID or sth.). For example if a user closes his ticket only a ticket_event will be created, not a ticket_replie. The ticket was created (ticket_replie & ticket_event), user answered something and now he closed his ticket (ticket_event created). I would like to have my array in this order:

ticket event(created)
first answer
second answer
ticket event (closed)

When I use this code:

$ticket_replies = $this->ticket_replies->sortBy('created_at');
    $ticket_events = $this->ticket_events->sortBy('created_at');

     $events_replies = $ticket_events->merge($ticket_replies);
     dd($events_replies);

It returns this order of $event_replies:

http://puu.sh/nPJP4/9f62a43ec2.png

How can I order them, so I get the order I would like to retrieve? Not each ticket_event is "related" to a ticket_replie.

jlrdw's avatar

Okay you need a one-to-many relationship one ticket may have many replies study up on one to many in the documentation and set things up that way. There is an intermediate tutorial right into the documentation take that tutorial. But I am positive a one-to-many will do the trick.

Snapey's avatar

The example I provided orders them by created date and is only possible because both collections contain a created_at field.

You need to say if you need them ordered in some other way.

I have not assumed or mentioned that the ticket_event and ticket_replie are linked in any way other than the fact that they have the same ticket_id

Please copy my example and sort the merged collection, and NOT sort them first and then merge.

jekinney's avatar

Default eloquent collections are sorted by id. Thus in theory unless you override the timestamps would be already sorted by created_at. Hence in my code snippet I left it out.

t0berius's avatar

@Snapey

I don't understand how I need to order them using your example, so I get an array of entries like I described in my last post.

jlrdw's avatar

If you would dig into those docs and fully understand how a one-to-many relationship works that would answer all of your questions. There's also videos on one to many relationships.

t0berius's avatar

@jlrdw

There is no direction between ticket_replie and ticket_event. I can't use an ID or something. Think you don't understand my problem.

Snapey's avatar

You get the two collections

You merge them

You pass the merged collection to the view

You iterate (foreach) over the collection, but apply a sort in the process

foreach($events_replies->sortBy('created_at') as $record)

try your existing code with

dd($events_replies->sortBy('created_at'));

And if that still does not work as you want, you are going to have to explain what the rule is for ordering the items

jlrdw's avatar

I have reread the question 10 times this is a one-to-many relationship. Every event you ever reply starts out with a ticket event, without a ticket event you don't have any replies it all has to be anchored to something to start out with. I'm taking it this is something like one of those cpanel problems when you submit a ticket and you get replies it is absolutely a one-to-many relationship.
It's probably a good time to rethink your setup on this.
Are you not pulling these records from a database?

Snapey's avatar

@jlrdw There are already one to many relationships A ticket has many ticket_events. A ticket also has many ticket_replies. Both are one to many and each event and reply has a ticket_id to track this relationship. There is NO relationship between events and replies, they just both relate to the same ticket.

Or to make it simpler.

Suppose you (Person) have owned motorbikes and cars. You could have a model for cars and a model for motorbikes. Since they have different attributes the two models could be different. There is no relationship between motorbikes and cars other than they have been owned by the same person.

What if you wanted to list all your motorbikes and cars in the order in which you bought them? This is the problem I have been trying to help with.

If any design change is needed, it would probably be to introduce a polymorphic relationship, but that's quite an advanced topic (IMO).

Next

Please or to participate in this conversation.