我已经实现了没有Eloquent的关系,但我想知道是否有一种方法可以在Eloquent中定义这种关系,以便我的应用程序可以更加一致。
table User
-id
-other user attributes
table friend_requests:
-id
-sender_id
-reciever_id
table friends
-id
-first
-second
在Eloquent中很容易实现friendRequest关系,但问题在于Friends。
如果我在User模型类中执行此操作:
public function friends(){
return $this->belongsToMany(User::class,'friends','first','second');
}
这不会像你所注意到的那样起作用。让我用例子解释一下:
Table: friends
id | first | second
1 | 1 | 2
2 | 3 | 1
您发现user_1
是user_2
以及user_3
的朋友,因为这种关系是双向的。但Eloquent自然会返回user_1
只有user_2
的朋友。经过一段时间的思考后,我调整了陈述,但收效甚微
public function friends(){
return $this->belongsToMany(User::class,'friends','first','second')
->orWhere('second',$this->id);
}
这是因为现在它选择了两行,但它返回的User
是id
= second
的那些,这意味着在第二种情况下它将返回用户本身。 / p>
我在User
模型类中使用我自己的方法实现了关系,使用DB::table('friends')->
到addFriend(User $user)
,removeFriend(user $user)
并返回friends()
的列表,但我和令人失望的是,这并不像Eloquent
关系那样雄辩。
也许在这里有一些经验丰富的开发人员会遇到这样的问题,而且比我做得更好。你怎么建议我处理这个问题。我应该坚持我的方法还是有更好的方法来处理它?</ p>
答案 0 :(得分:2)
实现双向关系的一种更易于管理的方法是为每个确认的友谊创建两个条目。
因此,用户可以向其他用户发送朋友请求。当第二个用户确认好友请求时,会创建两个友谊。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\User;
use App\FriendRequest;
use App\Friendship;
class FriendshipController extends Controller
{
public function friendRequest(Request $request)
{
$receiver_id = $request->input('receiver_id');
$request->user()->friend_offers()->create([
'receiver_id' => $receiver_id
]);
}
public function friendshipConfirmation(Request $request)
{
$friend_request_id = $request->input('friend_request_id');
$friend_request = FriendRequest::find($friend_request_id);
$friend_request->receiver->friendships()->create([
'user_2_id' => $friend_request->sender->id
]);
$friend_request->sender->friendships()->create([
'user_2_id' => $friend_request->receiver->id
]);
}
}
(注意receiver
和复数users
表的正确拼写)
table users
- id
- other user attributes
table friend_requests:
- id
- sender_id
- receiver_id
table friendships
- id
- user_1_id
- user_2_id
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable
{
use SoftDeletes;
public $timestamps = true;
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
//
];
/**
* Return friend requests from other users
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function friend_requests()
{
return $this->hasMany(FriendRequest::class, 'receiver_id');
}
/**
* Return friend requests sent to other users
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function friend_offers()
{
return $this->hasMany(FriendRequest::class, 'sender_id');
}
/**
* Return friendships with other users
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function friendships()
{
return $this->hasMany(Friendship::class, 'user_1_id');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class FriendRequest extends Model
{
use SoftDeletes;
public $timestamps = true;
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'sender_id',
'receiver_id'
];
/**
* Return the requesting user
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function sender()
{
return $this->belongsTo(User::class, 'sender_id');
}
/**
* Return the receiving user
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function receiver()
{
return $this->belongsTo(User::class, 'receiver_id');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Friendship extends Model
{
use SoftDeletes;
public $timestamps = true;
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_1_id',
'user_2_id'
];
/**
* Return user_1
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function first()
{
return $this->belongsTo(User::class, 'user_1_id');
}
/**
* Return user_2
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function second()
{
return $this->belongsTo(User::class, 'user_2_id');
}
}