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

El_Matella's avatar

A twitter like Feed

Hi, I have some problem resolving an SQL request problem. And I wonder if that is even possible. Let's imagine a twitter user page. On that page, they are the tweets a user has posted, but also the tweets a user has retweeted. But not in the order of the initial tweet, but in the order of the tweet/retweet.

Let's take an example. Let's say, Bootstrap sends a tweet. After that, I tweet something. And after that, I retweet the Bootstrap tweet. My user profile will show the bootstrap tweet in first position, then my tweet. So the ordering of the tweets take in consideration the time of the retweet, not the time from the initial tweet. Otherwise, I would have my tweet in first position, and the bootstrap one in second position.

So I have three tables:

users:
    - id
    - username
tweets: 
   - id
   - user_id
   - content
   - timestamps
retweet_user:
   - tweet_id
   - user_id
   - timestamps

What happens, is that when a user tweets something, it doesn't have an entry in the "retweet_user" table, because it already has an entry on the tweet table (with user_id).

I managed to make this request, which lists the tweets that I want, but not in the regular order obviously:

$tweets = Tweet::with('user')
    ->where('user_id',$user->id)
    ->orWhereHas('retweeters', function($query) use($user) {
        $query->where('id',$user->id);
    })->orderBy('id','desc')->get();

So here are the two solutions I found for my problem:

  • The easy one: When a user tweets, an entry is also made in the retweet_table, and I juste have to sort the results by the timestamp of this table.
  • The one I would like to do: Order the results by a virtual field called "time" for example. If the result is from the first where('user_id',$user->id'), it stores the created_at from the tweets table. If the result is from the orWhereHas(...), it stores the value of the created_at from the pivot table. I just would have to orderBy this virtual field, and it would work! Is this possible?

Thanks for the advices, and let me know if I was not clear in my explanations,

Many thanks! :)

0 likes
2 replies
willvincent's avatar
Level 54

I think you'd probably want to treat retweets as if they are the same action as a tweet.. so regardless if it's an original tweet, or retweet, you're ordering based on the time of the action. The easiest way to handle that may be to abstract the 'action' away from the actual messages.

So 'actions' would be a polymorphic relationship between tweets and retweets, that reference the specific tweet that was tweeted, and have their own timestamp of when that action occurred. From there the rest is more or less just display logic I think.

El_Matella's avatar

Sorry to respond this late!

Your answer seems to be a very good option for me, I looked at the Polymorphic Relationships Documentation and it seems that I should be able to retrieve all the information I need. Thank you very much for the tip! I wasn't a big fan of mixing data that does not represented the same thing in a table. But with that actions table, it feels like it's right :)

Please or to participate in this conversation.