Felipe Martins
Felipe Martins

Reputation: 11

Include user's shared posts into posts list

I have a timeline in my app just like Facebook where I list all posts from a user. I Also have a function to share a post and store it in a table named post_shares. How can I include a user's shared posts in the same collection of the model Post?

(Example Tables)

posts: id,user_id,title,desc

post_shares: id,post_id,user_id

In my view i do something like foreach($user->posts as $post) and i get all user posts, but i'd like to fetch the user's shared posts too.

What would be the best way to do this?

Upvotes: 1

Views: 556

Answers (2)

Jan Wytze
Jan Wytze

Reputation: 3497

Create a many to many relationship for the shared_posts: https://laravel.com/docs/5.4/eloquent-relationships#many-to-many
Here is an untested example.

public function sharedPosts()
{
    //Probably can be shorter, look at the laravel docs.
    return $this->belongsToMany('App\Post', 'post_shares', 'post_id', 'user_id');
}

Now you have 2 collections with both post models. One with the users posts and one with the users shared posts. Then you can merge both collections:

$posts->merge($sharedPosts)->sortBy('created_at');

The only problem about this is that you can't tell what post is a shared one and what not. But this can be fixed by the following function

public function getAllPostsAttribute()
{
    $posts = $this->posts()->selectRaw('"user_post" AS type')->get();
    $sharedPosts = $this->sharedPosts()->selectRaw('"shared_post" AS type')->get();

    return $posts->merge($sharedPosts)->sortBy('created_at');
}

You can now call the allPosts attribute on a user and get all posts and shared posts. You can distinguish the 2 by the type attribute on post.

I haven't tested anything of this so please let me know if there is an error.

The other method could be an mysql union.

Upvotes: 1

JLGarcia
JLGarcia

Reputation: 336

Based on the structure you just set the easiest way to go is with a JOIN in your SQL query.

If you are using MySQL it will look like this:

SELECT id, user_id, title, desc 
FROM posts p

INNER JOIN shares s 
ON s.post_id = p.id

You can keep adding all the logic you need within the query and the result should be a mix with all the needed info.

Upvotes: 0

Related Questions