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

msiri's avatar
Level 1

Create an up to date feed

Hi everyone, i've a 3 entities called Opportunity, Reply and Comments. I would like to order every item by the created_at attribute (last created first).

For this i've created 3 different query

$newsReply = Reply::orderBy('id', 'desc')->take(3)->get();
$newsOpportunity = Opportunity::orderBy('id', 'desc')->take(3)->get();
$newsComment = Comment::orderBy('id', 'desc')->take(3)->get();

And then i put it into an array, so the result is like this

array:3 [▼
  0 => Collection {#676 ▼
    #items: array:3 [▼
      0 => Reply {#677 ▼
        #fillable: array:15 [▼
          0 => "opportunity_id"
          1 => "association_id"
          2 => "media_name"
          3 => "title"
          4 => "description"
          5 => "changing_number"
          6 => "like"
          7 => "winner"
          8 => "coherence"
          9 => "creativity"
          10 => "clarity"
          11 => "personal"
          12 => "average"
          13 => "cover"
          14 => "declined"
        ]
        #connection: "mysql"
        #table: "replies"
        #primaryKey: "id"
        #keyType: "int"
        +incrementing: true
        #with: []
        #withCount: []
        #perPage: 15
        +exists: true
        +wasRecentlyCreated: false
        #attributes: array:17 [▼
          "id" => 4
          "opportunity_id" => 2
          "association_id" => 1
          "title" => "dwfnkjwenf"
          "description" => "aa"
          "changing_number" => 0
          "winner" => 0
          "coherence" => 0.0
          "creativity" => 0.0
          "clarity" => 0.0
          "personal" => 0.0
          "average" => 0.0
          "cover" => "1559037254.jpg"
          "document_file" => null
          "created_at" => "2019-05-28 11:54:14"
          "updated_at" => "2019-05-29 09:33:15"
          "declined" => 0
        ]
        #original: array:17 [▶]
        #changes: []
        #casts: []
        #dates: []
        #dateFormat: null
        #appends: []
        #dispatchesEvents: []
        #observables: []
        #relations: []
        #touches: []
        +timestamps: true
        #hidden: []
        #visible: []
        #guarded: array:1 [▶]
      }
      1 => Reply {#678 ▶}
      2 => Reply {#679 ▶}
    ]
  }
  1 => Collection {#713 ▼
    #items: array:3 [▼
      0 => Opportunity {#714 ▶}
      1 => Opportunity {#715 ▶}
      2 => Opportunity {#716 ▶}
    ]
  }
  2 => Collection {#750 ▼
    #items: array:3 [▼
      0 => Comment {#751 ▶}
      1 => Comment {#752 ▶}
      2 => Comment {#753 ▶}
    ]
  }
]

Or if you have an easier way to do so it's welcome

0 likes
15 replies
msiri's avatar
Level 1

@MUSHOOD - I've checked it, but it's the same as

Reply::orderBy('id', 'desc')->take(3)->get();
mushood's avatar

Yep.

I dont really see any way to do this simpler.

You fetch 3 different models and then place them in an array. Maybe you can share what you are doing after with the array and so on. But if thats how far you are going, then i guess that's it. One further suggestion would be to create an associative array instead:

$array['reply'] = ....;
$array['opportunity'] = ....;
.
.
.

That way you dont need to remember which one is first or second.

msiri's avatar
Level 1

@MUSHOOD - Unfortunately I'm stuck here, I don't know how to compare all the data of the array and then reorder it by most recent date. If you have any suggestions please, share with me!

msiri's avatar
Level 1

@MUSHOOD - This is working fine bro! But there’s a problem, in the second merge i lost the $newsReply element…

See this

$merged = $newsReply->merge($newsOpportunity);
dd($merged);
$merged = $merged->merge($newsComment);

This it’s what i get

Collection {#515 ▼
  #items: array:4 [▼
    0 => Reply {#678 ▶}
    1 => Reply {#679 ▶}
    2 => Opportunity {#714 ▶}
    3 => Opportunity {#715 ▶}
  ]
}

But with this

$merged = $newsReply->merge($newsOpportunity);
$merged = $merged->merge($newsComment);
dd($merged);

I lost Reply items

Collection {#514 ▼
  #items: array:4 [▼
    0 => Comment {#750 ▶}
    1 => Comment {#751 ▶}
    2 => Opportunity {#714 ▶}
    3 => Opportunity {#715 ▶}
  ]
}

I try this instead but not working…

$merged =  $newsReply>merge([$newsOpportunity,newsComment]);
$merged->all();

Any suggestions?

mushood's avatar

try this:

$merged = new \Illuminate\Database\Eloquent\Collection; 
$merged = $merged->merge($newsReply);
$merged = $merged->merge($newsOpportunity);
$merged = $merged->merge($newsComment);
mushood's avatar
mushood
Best Answer
Level 41

Hey I found the solution here: https://medium.com/@tadaspaplauskas/quick-tip-laravel-eloquent-collections-merge-gotcha-moment-e2a56fc95889

Its because reply and news have the same id. So this should work

$merged = new \Illuminate\Database\Eloquent\Collection; 
foreach ($newsReply as $reply)
    $merged->push($reply);
foreach ($newsOpportunity as $opportunity)
    $merged->push($opportunity);
foreach ($newsComment as $comment)
    $merged->push($comment);
1 like
mushood's avatar

@robstar Yes, but it can cause unexpected results when I was looking into it. I preferred not to chain just to be on the safe side

Please or to participate in this conversation.