Laravel 多对多关系字段名称
Laravel Many-to-Many Relationship Field Names
我有一个用户 table 和一个权限 table。一个用户可以有多个权限,一个权限可以有多个用户:
USER ID | PERMISSION ID
1 | 1
1 | 2
2 | 1
2 | 1
根据 Laravel 规范的定义,有一个名为 permission_user 的链接 table,用于自动推断这些 table。
如果我定义如下函数:
用户模型:
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) 无法从链接 table 中辨别出 permission_id 是对 permission.id 字段的外部引用的字段,即使数据库迁移反映出 user_id 是对 user.id 的外部引用,而 permission_id 是对 permission.id.
的外部引用
我可以通过在 belongsToMany 函数中指定链接 table 名称、字段名称和外键名称来解决这个问题,但是,Laravel 自己的文档指出不需要这样做当 tables 和字段被适当命名时,我的就是。这是 Laravel 中的错误吗?我需要更改 permission_user.permission_id 字段的名称吗?我该如何解决这个问题而不必在我的模型中指定这些名称,因为根据 Laravel(5.8) 的文档,这很耗时而且不需要。
根据 laravel 文档:
[...] Many users may have the role of "Admin". To define this relationship, three database tables are needed: users
, roles
, and role_user
. The role_user
table is derived from the alphabetical order of the related model names, and contains the user_id
and role_id
columns.
链接 table 必须仅包含每个模型的外键。否则,您需要指定正在使用的关系 table 以及每个关系模型的主键,如 laravel 文档中所指定。
正如我在评论部分所说,如果您创建 permission_user
table 只有 permission_id
和 user_id
列并将此列作为主键,它将按预期工作:
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 is a package that i have developed to handle user permissions and you can check the user_has_permissions
table definition, which is, basically, a table that does exactly what your permission_user
table does, by clicking this link.
希望对您有所帮助。
我有一个用户 table 和一个权限 table。一个用户可以有多个权限,一个权限可以有多个用户:
USER ID | PERMISSION ID
1 | 1
1 | 2
2 | 1
2 | 1
根据 Laravel 规范的定义,有一个名为 permission_user 的链接 table,用于自动推断这些 table。
如果我定义如下函数:
用户模型:
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) 无法从链接 table 中辨别出 permission_id 是对 permission.id 字段的外部引用的字段,即使数据库迁移反映出 user_id 是对 user.id 的外部引用,而 permission_id 是对 permission.id.
的外部引用我可以通过在 belongsToMany 函数中指定链接 table 名称、字段名称和外键名称来解决这个问题,但是,Laravel 自己的文档指出不需要这样做当 tables 和字段被适当命名时,我的就是。这是 Laravel 中的错误吗?我需要更改 permission_user.permission_id 字段的名称吗?我该如何解决这个问题而不必在我的模型中指定这些名称,因为根据 Laravel(5.8) 的文档,这很耗时而且不需要。
根据 laravel 文档:
[...] Many users may have the role of "Admin". To define this relationship, three database tables are needed:
users
,roles
, androle_user
. Therole_user
table is derived from the alphabetical order of the related model names, and contains theuser_id
androle_id
columns.
链接 table 必须仅包含每个模型的外键。否则,您需要指定正在使用的关系 table 以及每个关系模型的主键,如 laravel 文档中所指定。
正如我在评论部分所说,如果您创建 permission_user
table 只有 permission_id
和 user_id
列并将此列作为主键,它将按预期工作:
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 is a package that i have developed to handle user permissions and you can check the user_has_permissions
table definition, which is, basically, a table that does exactly what your permission_user
table does, by clicking this link.
希望对您有所帮助。