php - Laravel 5.5 用户模型和好友关系(belongsToMany)由多列组成

标签 php mysql laravel laravel-5

问题

我为我的 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      |
     +----------------------+

如果当前用户 ID = 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
//...
class User extends Model {
//...
    public function friends() {
        return $this->hasMany(/*...*/)->orWhere('uid2', $this->id);
    }
//...

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

例如,上面的代码可能会生成如下所示的 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);
}
//...

但是这样您就可以两次单独前往数据库。

关于php - Laravel 5.5 用户模型和好友关系(belongsToMany)由多列组成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46313538/

相关文章:

mysql - 在 MySQL 中转换日期

php - Joomla 1.5 : How to find number of concurrent/active users in my joomla based intranet system

MySQL 客户端连接

Laravel 仅为活跃用户选择帖子和评论

php - ftp_put() : Command STOR failed

php - 如何使用 jquery ajax 获取 api 数据?

php - 严格标准 vs fatal error /具体扩展 vs 抽象实现

javascript - 如何通过 PHP 填充 Bootstrap 弹出窗口

php - 文本中单词的出现次数(以及相似词)

php - 如何为IE8设置边框半径