我有一个用户表和一个权限表。一个用户可以拥有许多权限,而一个许可可以拥有许多用户:
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是对permit.id的外部引用的字段,即使数据库迁移反映出user_id是对user.id和permission_id的外部引用是对Permissions.id的外部引用。
我可以通过在belongsToMany函数中指定链接表名称,字段名称和外键名称来解决此问题,但是,Laravel自己的文档指出,当适当命名表和字段时,不需要使用此名称。这是Laravel中的错误吗?我是否需要更改permission_user.permission_id字段的名称?如何解决此问题而不必在模型中指定这些名称,因为这很耗时,根据Laravel(5.8)的文档不需要。
答案 0 :(得分:1)
根据laravel文档:
[...]许多用户可能具有“管理员”角色。要定义这种关系,需要三个数据库表:
users
,roles
和role_user
。role_user
表是从相关模型名称的字母顺序得出的,并且包含user_id
和role_id
列。
链接表必须仅包含每个模型的外键。否则,您需要按照laravel文档中的说明,指定要使用的关系表以及每种关系模型的主键。
正如我在评论部分中所述,如果您创建的permission_user
表仅包含permission_id
和user_id
列并将此列作为主键,它将按预期工作: / p>
Schema::create('permission_user', function (Blueprint $table) {
$table->unsignedBigInteger('permission_id');
$table->unsignedBigInteger('user_id');
$table->foreign('permission_id')->references('id')->on('permissions');
$table->foreign('user_id')->references('id')->on('users');
$table->primary(['permission_id', 'user_id']);
});
Here是我为处理用户权限而开发的一个软件包,您可以检查user_has_permissions
表定义,该表定义基本上是一个与您的permission_user
表完全相同的表单击this link。
希望有帮助。