【问题标题】:Laravel 5.5 User model and friends relationship (belongsToMany) by multiple columnsLaravel 5.5 多列用户模型和好友关系(belongsToMany)
【发布时间】:2018-03-01 00:17:32
【问题描述】:

问题

我为我的 Laravel 应用创建了一个简单的友谊关系,一切正常,直到我注意到当我查询用户的友谊时,它只会在 UID1 字段上搜索当前用户。

由于友谊本质上是一种双向关系,我试图在 laravel 模型中找到一种方法来通过多个列检索所有友谊关系。

当前实施

    public function friends()
    {
        return $this->belongsToMany( App\Modules\Users\Models\User::class ,'friends', 'uid1');
    }

理想的实现

    public function friends()
    {
        $a = $this->belongsToMany( App\Modules\Users\Models\User::class ,'users_friends', 'uid1');
        $b = $this->belongsToMany( App\Modules\Users\Models\User::class ,'users_friends', 'uid2');

        return combine($a,$b);

    }

表结构

     +----------------------+
     | users table          |
     +----------------------+
+----|   id: primary UserID |
|    |   fname: string      |
|    +----------------------+
|    
|    
|    +----------------------+
|    | friends table        |
|    +----------------------+
|    |   id: primary iD     |
|    |                      |
+----|   uid1: user_id      |
|    |                      |
+----|   uid2: user_id      |
     +----------------------+

根据下面朋友表中的数据,如果 Current UserID = 1,当前的实现只会返回其中 1 条记录。

     +-------------------------------+
     |      friends table (data)     |
     +--------|---------|------------+
     |   id   |  uid1   |   uid2     |
     +--------|---------|------------+
     |    1   |   1     |    7       |
     |    2   |   7     |    1       |
     |    3   |   9     |    1       |
     +-------------------------------+      

用户模型

<?php

namespace App\Modules\Users\Models;

use Illuminate\Database\Eloquent\Model;


class User extends Model
{


    protected $table = 'users';


    protected $fillable = [
        'username', 'email', 'password', .... . 
    ];


    public function friends()
    {
        return $this->belongsToMany( App\Modules\Users\Models\User::class ,'users_friends', 'uid1');

    }

环境

  • 服务器 = Homestead/linux
  • PHP = 7
  • MySQL

更新

我创建了一个 FriendShip 帮助器类,它做类似的事情,但是在这个函数中我明确地传入了 UserID

Friendship::where( [
                    [ 'uid1' ,'=', $uid],
                ])->orWhere( [
                    [ 'uid2', '=', $uid]
                ])->all();

【问题讨论】:

    标签: php mysql laravel laravel-5


    【解决方案1】:

    在声明关系时,您可以通过简单地链接来添加附加条件。

    <?php
    //...
    class User extends Model {
    //...
        public function friends() {
            return $this->hasMany(/*...*/)->orWhere('uid2', $this->id);
        }
    //...
    

    但请记住,eloquent 不会将关系的第一个条件分组在括号中,因此您可能会以在某些情况下无法按预期工作的 SQL 结尾(如果使用 应该没问题)

    例如,上面可能会产生如下所示的 SQL

    SELECT * FROM users_friends WHERE uid1 = ? AND uid1 IS NOT NULL OR uid2 = ?
    

    这是一个正确的 SQL 语句,但如果没有分组,您将不会得到您期望的结果。

    另一种方法是使用accessor 和两个独立的关系

    <?php
    //...
    public function friends1() {
        return $this->belongsToMany(User::class, 'users_friends', 'uid1');
    }
    
    public function friends2() {
        return $this->belongsToMany(User::class, 'users_friends', 'uid2');
    }
    
    public function getFriendsAttribute() {
        return $this->friends1->merge($this->friends2);
    }
    //...
    

    但是这样你就可以去 DB 两次。

    【讨论】:

    • 感谢@Michal Bieda,在您的第二个解决方案中,您正在执行数组合并。返回的不是集合还是 BelongsToMany 对象?
    • 嘿,这完全有效!太感谢了。反响也很大。感谢您提供详细信息。
    • 你说得对,Laravel 尽可能使用它的 Collection 类,我已经编辑了答案来纠正这个问题。
    猜你喜欢
    • 2018-07-11
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2018-06-27
    • 2018-04-18
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    相关资源
    最近更新 更多