【发布时间】:2020-01-09 19:12:53
【问题描述】:
我有一个用户表和一个权限表。一个用户可以有多个权限,一个权限可以有多个用户:
USER ID | PERMISSION ID
1 | 1
1 | 2
2 | 1
2 | 1
Laravel 规范定义了一个名为 permission_user 的链接表,用于自动推断这些表。
如果我定义以下函数:
用户模型:
public function Permissions()
{
return $this->belongsToMany('App\Permission');
}
权限模型:
public function Users()
{
return $this->belongsToMany('App\User');
}
我在调用App\User::first()->Permissions()->attach(App\Permission::first()); 时收到错误提示
Illuminate\Database\QueryException : SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'field list' (SQL: insert into `permission_user` (``, `user_id`) values (3, 1))
数据库迁移文件:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Carbon\Carbon;
use App\User;
use App\Permission;
use App\Http\Resources\User as UserResource;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('permissions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('username')->unique();
$table->string('name')->unique();
$table->string('email')->unique();
$table->boolean('verified');
$table->timestamps();
});
Schema::create('permission_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('permission_id');
$table->unsignedBigInteger('user_id');
$table->timestamps();
$table->foreign('permission_id')->references('id')->on('permissions');
$table->foreign('user_id')->references('id')->on('users');
});
$this->add_permission('View Projects');
$this->add_permission('Edit Projects');
$this->add_permission('View Users');
$this->add_permission('Edit Users');
$user = new User();
$user->name = 'John Smith';
$user->email = 'john@smith.com';
$user->username = 'jsmith';
$user->verified = 1;
$user->save();
$user->permissions()->attach(Permission::where('name','View Users')->first()->id); // -> This line it can't tell that permission_user.permission_id is where the permission.id field goes;
$perms = $user->permissions()->get();
foreach($perms as $perm)
{
echo $perm->name . '\n';
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
Schema::dropIfExists('permission_user');
Schema::dropIfExists('project_user');
Schema::dropIfExists('permissions');
Schema::dropIfExists('deployment_log');
Schema::dropIfExists('branches');
Schema::dropIfExists('projects');
Schema::dropIfExists('users');
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
private function add_permission($permission_name)
{
DB::table('permissions')->insert(
array(
'name' => $permission_name,
)
);
}
}
看起来 Laravel(5.8) 无法从链接表中辨别出 permission_id 是对 permission.id 字段的外部引用的字段,即使数据库迁移反映 user_id 是对 user.id 和 permission_id 的外部引用是对permission.id 的外部引用。
我可以通过在 belongsToMany 函数中指定链接表名、字段名和外键名来解决这个问题,但是,Laravel 自己的文档指出,当表和字段被适当命名时,这不是必需的,我的是。这是 Laravel 中的错误吗?我需要更改permission_user.permission_id 字段的名称吗?我如何解决这个问题而不必在我的模型中指定这些名称,因为根据 Laravel(5.8) 的文档,这既费时又不需要。
【问题讨论】:
-
您的数据库中是否存在权限?它们是实际存储的吗?
-
您是否尝试使用仅包含
user_id和permission_id字段且没有时间戳和 ID 的permission_user表?另外,将user_id和permission_id都设置为该表的主键。 -
你能发布你的完整权限模型吗?
-
@MateusJunges 看起来解决了它。我在带有时间戳的链接表上有一个主键 ID,不知道为什么这很重要,因为这是非常标准的东西。
-
要按预期工作,链接表必须只包含关系的每个模型的主键。如果您需要这些附加列,则必须在定义
belongsToMany关系时指定您的关系表和每个表的主键。
标签: laravel eloquent eloquent-relationship