Lumen / Laravel-为什么将数据自动插入到联结表中?

问题描述 投票:0回答:1

我有3张桌子:

Ad_users

广告组

Ad_usersxad_groups

Ad_usersxad_groups是其他两个的联接表。现在,我正在做一个流明/ Laravel项目,我们正在使用雄辩的模型。我的ad_users表和ad_groups表具有以下模型:

ad_user.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Ad_user extends Model
{
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
    'common_name',
    'location',
    'description',
    'postalcode',
    'physical_delivery_office_name',
    'telephone_number',
    'initials',
    'street_address'
  ];

  /**
   * Hides pivot in return queries.
   *
   * @var array
   */
  protected $hidden = [
    'pivot'
  ];

  /**
   * Many-To-Many relationship.
   */
  public function ad_groups()
  {
    return $this->belongsToMany('App\Ad_group', 'Ad_usersxad_groups');
  }
}

ad_group.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Ad_group extends Model
{
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
    'name'
  ];

  /**
   * Hides pivot from return queries.
   *
   * @var array
   */
  protected $hidden = [
    'pivot'
  ];

  /**
   * Many-To-Many relationshipl.
   */
  public function ad_users()
  {
    return $this->belongsToMany('App\Ad_user', 'Ad_usersxad_groups');
  }

  public function extensiontables()
  {
    return $this->belongsToMany('App\extensiontables_registry', 'extensiontables_registryxad_groups');
  }

}

ad_groups和ad_user内部的数据基本上来自我们公司的LDAP服务器。因此,当用户登录时,中间件会建立与ldap的连接并检索用户数据。然后,数据将同步到我们的本地数据库,这意味着它已更新或已创建。仅出于完整性考虑,以下是用户访问登录路径时正在执行的代码:

AuthController.php

  public function login(Request $request)
  {
    $ldap = new LDAP;
    $jwt = new JWTAuth;
    $response = new Response;

    $this->validate($request, [
      'username' => 'string|required',
      'password' => 'string|required'
    ]);

    if(!$ldap->authenticateUser($request->username, $request->password))
    {
      return response()->json([
        'error' => 'User could not be authenticated'
      ], 401);
    }

    /**
     * Synchronizes the user's data from ldap with the local db.
     * Used for better performance and mitigating network overhead.
    */
    $ldap->syncData($request->username);

    $response->header('Authorization', 'Bearer '.$jwt->generateJWT($request->username));
    return $response;
  }

[这里,重要的部分是$ldap->syncData($request->username);。它调用执行此代码的LDAP.php:

LDAP.php

  public function syncData($username)
  {
    try
    {
      if(!$this->connect())
      {
        $this->disconnect();
        return false;
      }

      $userData = $this->getUser($username, [
        'cn',
        'l',
        'description',
        'postalcode',
        'physicaldeliveryofficename',
        'telephonenumber',
        'initials',
        'memberof',
        'streetaddress'
      ]);

      $user = Ad_user::updateOrCreate(
        ['common_name' => $userData['cn']],
        [
          'common_name' => $userData['cn'],
          'location' => $userData['l'],
          'description' => $userData['description'],
          'postalcode' => $userData['postalcode'],
          'physical_delivery_office_name' => $userData['physicaldeliveryofficename'],
          'telephone_number' => $userData['telephonenumber'],
          'initials' => $userData['initials'],
          'street_address' => $userData['streetaddress']
        ]
      );

      // Remove everything but the user roles
      foreach($userData['memberof'] as $key=>$role)
      {
        preg_match("/^CN=.+?,/", $role, $role);
        $userData['memberof'][$key] = substr($role[0], 3, -1);
      }

      // Loop through every role because updateOrCreate cant handle arrays
      foreach($userData['memberof'] as $value)
      {
        $roles[] = Ad_group::updateOrCreate(
          ['name' => $value],
          ['name' => $value]
        )->id;
      }

      // Syncs current roles received from ldap with the local db
      $user->ad_groups()->sync($roles);
    }
    catch(\Exception $e)
    {
      $error =  array("exception_code" => $e->getCode(), "error_message" => $e->getMessage());

      Log::error($error);
      return false;
    }
    finally
    {
      $this->disconnect();
    }
  }

我发现,每当用户登录系统时,记录就会插入到联结表中。每次,这意味着将创建大量冗余数据。我猜导致该问题的代码的重要部分是:

$user->ad_groups()->sync($roles)

例如,同一用户登录7次后,联结表如下所示:

select * from ad_usersxad_groups;
+------------+-------------+------------+------------+
| Ad_user_id | Ad_group_id | created_at | updated_at |
+------------+-------------+------------+------------+
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
|          1 |           1 | NULL       | NULL       |
|          1 |           2 | NULL       | NULL       |
|          1 |           3 | NULL       | NULL       |
|          1 |           4 | NULL       | NULL       |
|          1 |           5 | NULL       | NULL       |
|          1 |           6 | NULL       | NULL       |
|          1 |           7 | NULL       | NULL       |
|          1 |           8 | NULL       | NULL       |
|          1 |           9 | NULL       | NULL       |
|          1 |          10 | NULL       | NULL       |
|          1 |          11 | NULL       | NULL       |
|          1 |          12 | NULL       | NULL       |
+------------+-------------+------------+------------+

这既不是理想的也不是可以接受的,但是由于我对lumen / laravel以及此处使用的php LDAP API还是很陌生,所以我几乎不知道是什么原因会导致这种行为。噢,至少我很确定MySQL / MariaDB不会影响此行为,因为FOREIGN KEY没有附加CASCADE。

我想知道我在模型定义中是否做错了什么,但是我不知道什么是xD您的一些帮助将不胜感激^^

编辑:日志显示了角色数组:

[2020-01-31 08:57:27] local.INFO: array (
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 4,
  4 => 5,
  5 => 6,
  6 => 7,
  7 => 8,
  8 => 9,
  9 => 10,
  10 => 11,
  11 => 12,
)  
php mysql laravel ldap lumen
1个回答
0
投票

根据我的发现,我猜这是造成您的问题的原因:

$roles[] = Ad_group::updateOrCreate(
    ['name' => $value],
    ['name' => $value]
)->id;

应该是:

$roles[] = Ad_group::updateOrCreate(
    ['name' => $value]
)->id;

您两次使用相同的名称,但是只会创建一个组(然后更新)。但是结果将附加到$roles数组,从而导致在同步时附加两个相同的组。

© www.soinside.com 2019 - 2024. All rights reserved.