Laravel hasOne 通过枢轴 table
Laravel hasOne through a pivot table
所以我有2个模型,User & Profile,关系设置如下:
/**
* User belongs to many Profile
*
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function profiles()
{
return $this->belongsToMany('App\Models\Profile', 'user_profiles');
}
我有 3 个 tables、用户、配置文件和 user_profiles(枢轴 table)
我的用户 table 中有一个名为 active_profile
的列,其中填充了配置文件 ID。
如何建立关系,以便我可以像下面这样调用:
$user->active_profile
这样它将return active_profile中设置的id的所有个人资料信息?
您应该可以使用 find
获取资源
$user->profiles()->find($user->active_profile);
您可以像这样将方法添加到您的 User
模型中:
public function active_profile ()
{
return $this->profiles()
->find($this->active_profile);
}
然后您可以调用方法 $user->active_profile();
我可能是错的,但为什么不直接使用 belongsTo
关系呢?
public function active_profile()
{
return $this->belongsTo('App\Models\Profile', 'active_profile');
}
希望对您有所帮助!
您可以在数据透视表 table 中添加额外字段,例如 active = enum(y, n)
,然后设置 unique key (user_id, active)
,然后在用户模型中使用 wherePivot
方法:
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');
}
虽然它需要 DB 重构。
在 Laravel 5.8 上,因为我想将它与 eager loading 一起使用,所以我使用了这个包:
https://github.com/staudenmeir/eloquent-has-many-deep
这是我的场景
可以在多张照片上标记一个用户,而一张照片可以标记多个用户。我想建立关系以获取标记用户的最新照片。
我认为我的场景也可以应用于任何many-to-many关系
我做了枢轴模型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);
}
}
然后在我的 User 模型上使用 staudenmeir 的包:
<?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();
}
}
然后我可以很容易地做这样的事情:
User::with('latestPhoto')->get()
和 $user->latestPhoto
编辑:
在另一个问题中,有人在没有使用包的情况下提出了同样的问题。
我还提供了 会产生相同的结果。
但是在深入挖掘之后,从两个答案来看,您可能会避免 n+1 查询,您仍然会滋润来自您请求的用户的所有照片。我不认为可以避免一种或另一种方法。缓存可能是一个答案。
所以我有2个模型,User & Profile,关系设置如下:
/**
* User belongs to many Profile
*
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function profiles()
{
return $this->belongsToMany('App\Models\Profile', 'user_profiles');
}
我有 3 个 tables、用户、配置文件和 user_profiles(枢轴 table)
我的用户 table 中有一个名为 active_profile
的列,其中填充了配置文件 ID。
如何建立关系,以便我可以像下面这样调用:
$user->active_profile
这样它将return active_profile中设置的id的所有个人资料信息?
您应该可以使用 find
$user->profiles()->find($user->active_profile);
您可以像这样将方法添加到您的 User
模型中:
public function active_profile ()
{
return $this->profiles()
->find($this->active_profile);
}
然后您可以调用方法 $user->active_profile();
我可能是错的,但为什么不直接使用 belongsTo
关系呢?
public function active_profile()
{
return $this->belongsTo('App\Models\Profile', 'active_profile');
}
希望对您有所帮助!
您可以在数据透视表 table 中添加额外字段,例如 active = enum(y, n)
,然后设置 unique key (user_id, active)
,然后在用户模型中使用 wherePivot
方法:
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');
}
虽然它需要 DB 重构。
在 Laravel 5.8 上,因为我想将它与 eager loading 一起使用,所以我使用了这个包: https://github.com/staudenmeir/eloquent-has-many-deep
这是我的场景
可以在多张照片上标记一个用户,而一张照片可以标记多个用户。我想建立关系以获取标记用户的最新照片。
我认为我的场景也可以应用于任何many-to-many关系
我做了枢轴模型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);
}
}
然后在我的 User 模型上使用 staudenmeir 的包:
<?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();
}
}
然后我可以很容易地做这样的事情:
User::with('latestPhoto')->get()
和 $user->latestPhoto
编辑:
在另一个问题中,有人在没有使用包的情况下提出了同样的问题。
我还提供了
但是在深入挖掘之后,从两个答案来看,您可能会避免 n+1 查询,您仍然会滋润来自您请求的用户的所有照片。我不认为可以避免一种或另一种方法。缓存可能是一个答案。