1
votes

I'm trying write an website with Laravel (current version is 5.7) and I have 3 models as: Post, User and Fav. I'm using a simple form to add posts to "favs" table which has 3 columns as; id, user_id and post_id. And I want to list posts that user added favorites bu I can't use "hasMany" method properly.

I can use variables like; $post->user->name but I can't figure it out how to use relationship with "favs" table.

Post Model

public function user() {
    return $this->belongsTo('App\User');
}

public function favs() {
    return $this->hasMany('App\Fav');
}

Fav Model

public function users() {
    return $this->hasMany('App\User');
}
public function posts() {
    return $this->hasMany('App\Post', 'post_id', 'id');
}

User Model

public function posts() {
    return $this->hasMany('App\Post');
}

public function favs() {
    return $this->hasMany('App\Fav');
}

Controller

public function user($id){

    $favs = Fav::orderBy('post_id', 'desc')->get();
    $user = User::find($id);
    $posts = Post::orderBy('id', 'desc')->where('user_id', $id)->where('status', '4')->paginate(10);
    return view('front.user')->with('user', $user)->with('posts', $posts)->with('favs', $favs);
}
3
Are you trying to list within a laravel blade template?thisiskelvin
@thisiskelvin yes. In foreach loop with {{ }}Vito Andolini

3 Answers

1
votes

The Fav model only has one User and Post each, so you need to use belongsTo() instead of hasMany and change the method names to singular. You can also remove the additional parameters in post() since they're the default values.

public function user() {
    return $this->belongsTo('App\User');
}
public function post() {
    return $this->belongsTo('App\Post');
}

Loading all Posts that a user has favorited:

$user->favs()->with('post')->get();

The with() method is used to eager load the relationship.

Now you can loop through the Favs:

@foreach($favs as $fav)
{{ $fav->post->name }}
@endforeach
1
votes

I think you can change these two lines of your code to

$posts = Post::orderBy('id', 'desc')->where('user_id', $id)->where('status', '4')->paginate(10);
return view('front.user')->with('user', $user)->with('posts', $posts)->with('favs', $favs);

to

$posts = Post::where('user_id', $id)->where('status', '4')->latest()->paginate(10);
return view('front.user', compact('user', 'posts', 'favs'));

And for retrieving favorite posts of an user,

if you will change the fav table to make it a pivot table only to handle a many to many relationships between Post and User, you can get it as $user->posts, for a separate model, I think you can consider something like $user->favs and in view

In Fav model

public function user() {
    return $this->belongsTo('App\User');
}
public function post() {
    return $this->belongsTo('App\Post');
}

and in view

@foreach ( $user->favs as $fav )
    {{ $fav->post->id }}
@endforeach
0
votes

If an User, per example, have many Favs you need to use a Iteration Block, like foreach.

Example:

foreach($user->favs as $fav) {
    dd($fav) // do something
}

Ps.: Be careful not to confuse hasMany and belongsToMany.