问题
So I have 2 models, User & Profile, the relationship is set up as follows:
/**
* User belongs to many Profile
*
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function profiles()
{
return $this->belongsToMany('App\Models\Profile', 'user_profiles');
}
I have 3 tables, users, profiles & user_profiles (the pivot table)
I have a column in my users table called active_profile
which gets populated with a profile id.
How can I set up the relationship so that I can call something like the following:
$user->active_profile
So that it will return all the profile information for the id set in active_profile?
回答1:
You can add a method into your User
model like this :
public function active_profile ()
{
return $this->profiles()
->find($this->active_profile);
}
and then you can call the method as $user->active_profile();
回答2:
On Laravel 5.8, since I wanted to use it with eager loading I used this package: https://github.com/staudenmeir/eloquent-has-many-deep
This was my scenario
A user can be tagged on many photo and a photo can have many users tagged on. I wanted to have a relationship to get the latest photo the user has been tagged on.
I think my scenario can also be applied to any many-to-many relationship
I did the pivot model UserPhoto
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\Pivot;
class UserPhoto extends Pivot
{
public function user()
{
return $this->belongsTo(User::class);
}
public function photo()
{
return $this->belongsTo(Photo::class);
}
}
And then on my User model using staudenmeir's package:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
class User extends Model
{
use HasRelationships;
public function photos()
{
return $this->belongsToMany(Photo::class);
}
public function latestPhoto()
{
return $this->hasOneDeep(Photo::class, [UserPhoto::class])
->latest();
}
}
Then I can easily do something like this:
User::with('latestPhoto')->get()
and $user->latestPhoto
Edit: In an another question, someone asked the same without using a package. I also provided an answer that will do the same result.
But after digging deeper, from both answers, you may avoid the n+1 query, you will still hydrate all the photos from your requested users. I don't think it's possible to avoid one or the other approach. The cache could be an answer though.
回答3:
I could be wrong but why not just use a belongsTo
relationship?
public function active_profile()
{
return $this->belongsTo('App\Models\Profile', 'active_profile');
}
Hope this helps!
回答4:
You could add extra field in pivot table, for example active = enum(y, n)
, then set unique key (user_id, active)
and then use wherePivot
method in user model:
public function profiles()
{
return $this->belongsToMany('App\Models\Profile', 'user_profiles');
}
public function activeProfile()
{
return $this->belongsToMany('App\Models\Profile', 'user_profiles')->wherePivot('active', 'y');
}
It requires DB refactoring though.
回答5:
You should be able to grab the resource using find
$user->profiles()->find($user->active_profile);
来源:https://stackoverflow.com/questions/42033777/laravel-hasone-through-a-pivot-table