Reputation: 11
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
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
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