Laravel eloquent in dedicated relation table? - laravel

How to get multiple row from tags table using single id_post in eloquent.

I think you need to set a Many to many relation in your post and tag model:
Your Post Model:
public function tags()
{
return $this->belongsToMany('Tag');
}
Your Tag model:
public function posts()
{
return $this->belongsToMany('Post');
}
And then you can use Eloquent to get all tags associated to your post_id:
$tags = Post:find($post_id)->tags()->get();

$posts = Post::with('tags')->get();
foreach($posts as $post) {
$tags = $post->tags;
}
Now, this is assuming that you've setup your models as 'Post' and 'Tag'
If your Post model, you should have a tags method that says where to find the tags, something like:
public function tags()
{
return $this->belongsToMany('Tag');
}

Related

Many to Many Get All Distinct Values From a Related Model

I have an Article model with many-to-many relation with the Tag model
The Article model
class Article extends Model
{
public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
The Tag model
class Tag extends Model
{
public function articles()
{
return $this->belongsToMany(Article::class);
}
}
What I want is to get all the unique tags that have a relation with at least one (or more) article in the articles table. I want to retrieve it through a static method in the Article model like below
public static function allTags()
{
// return static:: all the tags
}
How can I do this? Thanks in advance.
EDIT: this is how I solved it. Appreciate the help!
public static function allTags()
{
return Tag::query()->whereHas('articles', function($query) {
$query->where('status', '<>', 'draft');
})->pluck('tag', 'id');
}
Using whereHas()
$tags = Tag::query()->whereHas('articles')->get();

how to retrive posts where their category is same with current post in laravel?

I have post and category many to many relationship where post and category model define correctly, I have pivot table to but no model for pivot table.
When I get one post I have the post categories to, $post->categories.
I want to list all post with current post categories, for exapmle if the current post have category of A and B, I want to retrieve all posts with category of A and B.
What is best and easiest way in laravel elequent for this purpose?
here my models if it help
class Post extends Model
{
public function categories(){
return $this->belongsToMany(Category::class);
}
}
class Category extends Model
{
public function posts(){
return $this->belongsToMany(Posts::class);
}
}
public function singlePost(Post $post){
$postsWithSameCategory = ???
return view('home.post',compact('post'));
}
If you want the posts with the same categories
From your example; posts with categorie A, B, A/B, A/B/C would be returned
public function singlePost(Post $post){
$postsWithSameCategory = Post::whereHas('categories', function($query) use ($post) {
$query->whereIn('id', $post->categories->pluck('id'));
})->get();
return view('home.post',compact('post', 'postsWithSameCategory'));
}
If you want the posts with the exact same categories
From your example; Only posts with categorie A/B would be returned
public function singlePost(Post $post){
$postsWithSameCategory = Post::whereHas('categories', function($query) use ($post) {
$query->whereIn('id', $post->categories->pluck('id'));
}, '=', $post->categories->count())->get();
return view('home.post',compact('post', 'postsWithSameCategory'));
}
To also answer your comment, you can define a scope your Post model
public function scopeWhereIsRelatedWithPost($query, $post)
{
return $query->whereHas(/** ... **/);
}
$posts = Post::whereIsRelatedWithPost($post)->get();

Getting filtered data from many to many relationship

I need to get filtered data from many to many relationship from Post and Tag tables.
I have Post Model:
class Post extends Model
{
public function tag()
{
return $this->belongsToMany('App\Tag', 'post_tag','post_id','tag_id');
}
}
And Tag Model like:
Class Tag extends Model
{
protected $fillable = ['name'];
public function post()
{
return $this->belongsToMany(Post::class, 'post_tag');
}
}
But when I try to get filtered data based on tag_id:
if($request->filled('tag_id')){
$posts = Post::whereHas(
['tag' => function($query) use($request)
{
$query->where('tag_id','=', $request->input('tag_id'));
}
])->get();
}
It doesnt work
according to laravel doc
whereHas take string and callback function as parameters not an array:
$posts = Post::whereHas(
'tag' ,function($query) use($request)
{
$query->where('tag_id','=', $request->input('tag_id'));
}
)->get();

Merging two queries into one using Eloquent

I have this two queries to display information in 3 tables Users, Comments, and Posts. so I made this function:
public function show($id)
{
$posts = Post::with(['comments'])->findOrFail($id);
$user = User::find($posts->user_id);
echo "<h1>".$posts->title.'</h1>';
echo "<h2>".$user->name.'</h2>';
foreach ($posts->comments as $comment) {
echo $comment->body.'<br>';
}
}
on this function I using two variable $posts and $user, can I merge this two variable using eloquests command like Post::with(['user','comments'])'? so I can use just $posts variable and use it like $posts->users->name to access user name.
i was trying using this way:
$posts = Post::with(['comments','users'])->findOrFail($id);
but when i echo the post it showing that the user was null:
{"id":1,"user_id":1,"title":"Oleh id 1","body":"ini adalah content","created_at":"2017-10-18 03:25:54","updated_at":"2017-10-18 03:25:54","comments":[{"id":1,"post_id":1,"body":"Keren banget deh artikelnya, TOP","created_at":"2017-10-18 03:43:50","updated_at":"2017-10-18 03:43:50"},{"id":2,"post_id":1,"body":"Keren banget deh artikelnya, TOP","created_at":"2017-10-18 03:43:53","updated_at":"2017-10-18 03:43:53"},{"id":3,"post_id":1,"body":"Keren banget deh artikelnya, TOP","created_at":"2017-10-18 03:43:54","updated_at":"2017-10-18 03:43:54"}],"users":null}
Here's my model if you need it. My post model:
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function comments()
{
return $this->hasMany('App\Comment');
}
public function users(){
return $this->belongsTo('App\User');
}
}
my Comment model
class Comment extends Model
{
/**
* Get the post that owns the comment.
*/
public function post()
{
return $this->belongsTo('App\Post');
}
}
You’ll have an easier time sticking to Laravel’s conventions for naming relationships.
A Post has many Comments, which belong to a User. Given this set up:
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
You can then query a post’s comments and users like this:
$comments = $post->comments()->with('user')->get();
You could also eager-load the user relation on comments if you always wanted the user returned with a comment:
class Comment extends Model
{
protected $with = ['user'];
public function user()
{
return $this->belongsTo(User::class);
}
}
Then your query would be simplified:
$comments = $post->comments;
Hope this helps you!!
What I am guessing is you want the list of all posts with the users. If relation is defined, try with the join
$posts = DB::table('posts')
->join('users', 'users.id', '=', 'posts.user_id')
->select('posts.*', 'users.name as user_name')
->where('posts.comments', '<>', NULL)
->get();
#NOTE: If you are using soft deletes you might wanna add where('posts.deleted_at', null)
After couple of days searching finally i got the answer, i can get merge the query like this:
$posts = Post::with(['comments','users'])->findOrFail($id);
but in the Post Model the function not "Users" but "User".

Laravel 4.1: proper way to retrieve all morphedBy relations?

Just migrated to 4.1 to take advantage of this powerful feature.
everything seems to work correctly when retrieving individual 'morphedByXxxx' relations, however when trying to retrieve all models that a particular tag belongs to -- i get an error or no results.
$tag = Tag::find(45); //Tag model name = 'awesome'
//returns an Illuminate\Database\Eloquent\Collection of zero length
$tag->taggable;
//returns Illuminate\Database\Eloquent\Relations\MorphToMany Builder class
$tag->taggable();
//returns a populated Collection of Video models
$tag->videos()->get();
//returns a populated Collection of Post models
$tag->posts()->get();
My Tag Model class loooks like this:
class Tag extends Eloquent
{
protected $table = 'tags';
public $timestamps = true;
public function taggable()
{
//none of these seem to function as expected,
//both return an instance of MorphToMany
//return $this->morphedByMany('Tag', 'taggable');
return $this->morphToMany('Tag', 'taggable');
//this throws an error about missing argument 1
//return $this->morphToMany();
}
public function posts()
{
return $this->morphedByMany('Post', 'taggable');
}
public function videos()
{
return $this->morphedByMany('Video', 'taggable');
}
}
And the Post and Video models look like this:
class Post extends Eloquent
{
protected $table = 'posts';
public $timestamps = true;
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
}
I am able to add/remove Tags to Posts and Videos as well as retrieve the related Posts, and Videos for any Tag -- however -- what is the proper way to retrieve all Models having the Tag name 'awesome'?
Was able to figure it out, would love to hear comments on this implementation.
in Tag.php
public function taggable()
{
return $this->morphToMany('Tag', 'taggable', 'taggables', 'tag_id')->orWhereRaw('taggables.taggable_type IS NOT NULL');
}
in calling code:
$allItemsHavingThisTag = $tag->taggable()
->with('videos')
->with('posts')
->get();
I just used this on Laravel 5.2 (not sure if it is a good strategy though):
Tag model:
public function related()
{
return $this->hasMany(Taggable::class, 'tag_id');
}
Taggable model:
public function model()
{
return $this->belongsTo( $this->taggable_type, 'taggable_id');
}
To retrieve all the inverse relations (all the entities attached to the requested tag):
#foreach ($tag->related as $related)
{{ $related->model }}
#endforeach
... sadly this technique doesn't offer eager load functionalities and feels like a hack. At least it makes it simple to check the related model class and show the desired model attributes without much fear to look for the right attributes on the right model.
I posted a similar question in this other thread as I am looking for relations not known in advance.

Resources