更有雄辩地界定多对多双向关系 [英] Defining many-to-many bidirectional relations more eloquently

查看:109
本文介绍了更有雄辩地界定多对多双向关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了这个关系,没有雄辩,但我想知道有没有办法定义这个关系在雄辩中,以便我的应用程序可以有更多的一致性。

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 Users 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆