更有雄辩地界定多对多双向关系 [英] Defining many-to-many bidirectional relations more eloquently
问题描述
我已经实现了这个关系,没有雄辩,但我想知道有没有办法定义这个关系在雄辩中,以便我的应用程序可以有更多的一致性。
I have implemented the relationship without Eloquent but I was wondering is there was a way to define this relationship in Eloquent so that my application can have more consistency.
table User
-id
-other user attributes
table friend_requests:
-id
-sender_id
-reciever_id
table friends
-id
-first
-second
friendRequest关系在雄辩中很容易实现,但问题在于朋友。
The friendRequest relation has been easily implemented in the Eloquent but the problem lies in Friends.
如果我在用户模型类:
public function friends(){
return $this->belongsToMany(User::class,'friends','first','second');
}
这不会像你注意到的那样工作。让我举个例子说明一下:
This wouldn't work as you would have noticed. Let me explain with example:
Table: friends
id | first | second
1 | 1 | 2
2 | 3 | 1
你看到 user_1
是朋友 user_2
以及 user_3
,因为关系是双向的。但雄辩自然会返回 user_1
是 user_2
的朋友。经过一段时间我调整了声明,但没有进展
you see that user_1
is friends with user_2
as well as user_3
as the relationship is bi-directional. But Eloquent will naturally return that user_1
is friends with user_2
only. After thinking for a while I tweaked the statement but made little progress'
public function friends(){
return $this->belongsToMany(User::class,'friends','first','second')
->orWhere('second',$this->id);
}
这是因为现在它选择了两行,但是用户
s返回是那些 id
= second
这意味着在第二种情况它将返回用户本身。
That is because now it selects both rows but the User
s it returns are those whose id
= second
which means that in the second case it will return the user itself.
我在 User
模型类中使用我自己的方法实现了关系, code> DB :: table('friends') - > to addFriend(User $ user)
, removeFriend(user $ user)
并返回 friends()
的列表,但我感到失望的是,这不如$ code>雄辩关系。
I implemented the relations with my own methods in User
model class which use DB::table('friends')->
to addFriend(User $user)
, removeFriend(user $user)
and returns list of friends()
, but I'm disappointed that this isn't as eloquent as Eloquent
relationships.
也许这里有一些更有经验的开发人员会遇到这样的问题,会比我更好没有。你如何建议我处理这个问题。我应该坚持使用我的方法吗?还是有更好的方法去处理?
Perhaps some more experienced developers here would have come across this kind of problem and would have dealt better than I did. How do you propose I deal with this problem. Should I stick with my approach or is there a better way to deal with it?
推荐答案
将为每个确认的友谊创建两个条目。
A more manageable way to implement bidirectional relations would be to create two entries for each confirmed friendship.
所以用户可以向另一个用户发送一个朋友请求。
So a user would make a friend request to another user. When the second user confirms the friend request, two friendships are created.
<?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
]);
}
}
数据库表
(请注意接收者
和复数用户
表的适当拼写)
Database Tables
(Note the proper spelling of receiver
and plural users
table)
table users
- id
- other user attributes
table friend_requests:
- id
- sender_id
- receiver_id
table friendships
- id
- user_1_id
- user_2_id
用户模型
User Model
<?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');
}
}
FriendRequest模型
FriendRequest Model
<?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');
}
}
友谊模型
Friendship Model
<?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');
}
}
这篇关于更有雄辩地界定多对多双向关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!